Last active
February 18, 2024 11:45
-
-
Save codeaid/5974560 to your computer and use it in GitHub Desktop.
PHP DAO generator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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