Skip to content

Instantly share code, notes, and snippets.

@codeaid
Last active February 18, 2024 11:45
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save codeaid/5974560 to your computer and use it in GitHub Desktop.
Save codeaid/5974560 to your computer and use it in GitHub Desktop.
PHP DAO generator
#!/usr/bin/php
<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
$host = '127.0.0.1';
$user = 'root';
$pass = '';
$db = 'test';
$namespace = 'Application\Model';
$parentClass = 'Application\Model\AbstractModel';
// class template
$classTemplate = '<?php
namespace {{NAMESPACE}};
use {{PARENT_CLASS_ABSOLUTE}};
class {{CLASS_NAME}} extends {{PARENT_CLASS_RELATIVE}}
{
{{PROPERTIES}}
{{METHODS}}
}
';
// individual property template
$propertyTemplate = ' /**
* @var {{PROPERTY_TYPE}}
*/
protected ${{PROPERTY_NAME}};
';
// setter template
$setterTemplate = ' /**
* Set value of {{PROPERTY_NAME}}
*
* @param {{PROPERTY_TYPE}} ${{PROPERTY_NAME}} Value to set `{{FIELD_NAME}}` to
* @return {{CLASS_NAME}}
*/
public function {{METHOD_NAME}}(${{PROPERTY_NAME}})
{
$this->{{PROPERTY_NAME}} = ${{PROPERTY_NAME}};
return $this;
}
';
// setter template
$getterTemplate = ' /**
* Get value of `{{FIELD_NAME}}`
*
* @return {{PROPERTY_TYPE}}
*/
public function {{METHOD_NAME}}()
{
return $this->{{PROPERTY_NAME}};
}
';
$mysqli = new Mysqli($host, $user, $pass, $db);
/* check connection */
if ($mysqli->connect_errno) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit(1);
}
// fetch list of tables
$sql = 'SHOW TABLES';
$tables = $mysqli->query($sql);
// loop through all tables and fetch their information
while ($table = $tables->fetch_array()) {
list($tableName) = $table;
$parentClassRelative = substr($parentClass, strrpos($parentClass, '\\') + 1);
// intialise the calss template
$params = array(
'NAMESPACE' => $namespace,
'PARENT_CLASS_ABSOLUTE' => $parentClass,
'PARENT_CLASS_RELATIVE' => $parentClassRelative,
'CLASS_NAME' => getClassName($tableName),
);
$template = processTemplate($classTemplate, $params);
// fetch table info
$sql = sprintf('DESCRIBE %s', $tableName);
$tableInfo = $mysqli->query($sql);
$fieldsTemplate = '';
$methodsTemplate = '';
// process each individual field
while ($fields = $tableInfo->fetch_array()) {
list($field, $type, $null, $key, $default, $extra) = $fields;
$fieldParams = array(
'PROPERTY_NAME' => getPropertyName($field),
'PROPERTY_TYPE' => getPropertyType($type),
);
$fieldsTemplate .= processTemplate($propertyTemplate, $fieldParams);
$methodsTemplate .= processTemplate($setterTemplate, array(
'PROPERTY_NAME' => getPropertyName($field),
'PROPERTY_TYPE' => getPropertyType($type),
'FIELD_NAME' => $field,
'METHOD_NAME' => getMethodName($field, 'set'),
'CLASS_NAME' => getClassName($tableName),
));
$methodsTemplate .= processTemplate($getterTemplate, array(
'FIELD_NAME' => $field,
'PROPERTY_NAME' => getPropertyName($field),
'PROPERTY_TYPE' => getPropertyType($type),
'METHOD_NAME' => getMethodName($field, 'get'),
));
}
$template = processTemplate($template, array(
'PROPERTIES' => trim($fieldsTemplate),
'METHODS' => trim($methodsTemplate),
));
// create the output directory if it does not exist
if (!file_exists('output')) {
if (!@mkdir('output')) {
var_dump(error_get_last());
exit(1);
}
}
$filename = sprintf('output/%s.php', getClassName($tableName));
file_put_contents($filename, $template);
printf("Model for table `%s` successfully saved in '%s'\n", $tableName, $filename);
}
/**
* Convert an underscore_separated string to its camelCase version
*
* @param string $value Value to process
* @return string
*/
function camelCase($value)
{
return preg_replace_callback('/_[a-z0-9]{1}/i', function($matches) {
return strtoupper(substr($matches[0], 1));
}, $value);
}
/**
* Get class name from the specified table name
*
* @param string $table Table name to process
* @return string
*/
function getClassName($table)
{
return ucfirst(camelCase($table));
}
/**
* Get property name from a field name
*
* @param string $field Field name to process
* @return string
*/
function getPropertyName($field)
{
return camelCase($field);
}
/**
* Get method name from a field name
*
* @param string $field Field name to process
* @param string $type Method type - `set` or `get`
* @return string
*/
function getMethodName($field, $type)
{
return $type . ucfirst(getPropertyName($field));
}
/**
* Replace values from the parameters into the template
*
* @param string $template Template base
* @param array $params List of parameters and their values
* @return string
*/
function processTemplate($template, array $params)
{
foreach ($params as $key => $value) {
$key = strtoupper($key);
$placeholder = sprintf('{{%s}}', $key);
$template = str_replace($placeholder, $value, $template);
}
return $template;
}
/**
* Convert MySQL specific field types to PHP types
*
* @param string $type MySQL field type (e.g. int(11), varchar(10), etc.)
* @return string
*/
function getPropertyType($type)
{
preg_match('/^(?P<type>[a-z]+)(?:\(\d+\))?/', $type, $matches);
if (!empty($matches['type'])) {
$type = $matches['type'];
}
$type = strtolower($type);
switch ($type)
{
case 'integer':
case 'int':
case 'smallint':
case 'tinyint':
case 'mediumint':
case 'bigint':
case 'timestamp':
case 'year':
case 'bit':
return 'int';
case 'varchar':
case 'char':
case 'tinytext':
case 'text':
case 'mediumtext':
case 'longtext':
case 'binary':
case 'varbinary':
case 'blob':
case 'date':
case 'time':
case 'datetime':
return 'string';
case 'double':
case 'numeric':
case 'decimal':
case 'float':
return 'float';
case 'enum':
default:
return 'mixed';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment