Last active
July 7, 2017 09:36
-
-
Save davebarnwell/9bef38967d30bead4230bbbf6871cce0 to your computer and use it in GitHub Desktop.
generate PHP docblock @properties from a mysql table, great when using magic setters and getters
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/env php | |
| <?php | |
| /** | |
| * Generate PHP Doc blocks @property values for a given table | |
| * helps when a class wraps a table and the class uses magic setters and getters | |
| * | |
| * Usage:- | |
| * ./propsOfTable.php {mysqlTableName} | |
| */ | |
| $database = 'your_database'; | |
| $user = 'your_db_user'; | |
| $password = 'your_db_password'; | |
| $db = new PDO($dsn = 'mysql:dbname=' . $database . ';host=127.0.0.1', $user, $password); | |
| $tableName = $argv[1] ?? null; | |
| if (empty($tableName)) { | |
| echo <<<HELP | |
| First parameter must be a table name in $database | |
| HELP; | |
| exit; | |
| } | |
| $obj = new mysqlTableToPhp($tableName, $db); | |
| $maxFieldNameWidth = 0; | |
| foreach ($obj->getPhpDocPropertyIterator() as $property) { | |
| $maxFieldNameWidth = max($maxFieldNameWidth, strlen($property->name)); | |
| } | |
| echo '/**' . PHP_EOL; | |
| echo ' * table fields : auto-generated by .' . __FILE__ . ' ' . $tableName . PHP_EOL; | |
| echo ' *' . PHP_EOL; | |
| foreach ($obj->getPhpDocPropertyIterator() as $property) { | |
| echo sprintf(" * @property %-6s $%-{$maxFieldNameWidth}s %s\n", $property->type, $property->name, | |
| $property->comment); | |
| } | |
| echo ' */' . PHP_EOL; | |
| class mysqlTableToPhp | |
| { | |
| private $tableName; | |
| private $db; | |
| public function __construct(string $tableName, PDO $db) | |
| { | |
| $this->tableName = $tableName; | |
| $this->db = $db; | |
| } | |
| /** | |
| * @return PDOStatement | |
| */ | |
| private function getTableColumnQuery() | |
| { | |
| return $this->db->query('SHOW columns FROM ' . $this->tableName); | |
| } | |
| /** | |
| * @return Generator | |
| */ | |
| public function getColumnIterator() | |
| { | |
| $result = $this->getTableColumnQuery(); | |
| while ($row = $result->fetchObject()) { | |
| yield $row; | |
| } | |
| } | |
| /** | |
| * @return Generator | |
| */ | |
| public function getPhpDocPropertyIterator() | |
| { | |
| foreach ($this->getColumnIterator() as $row) { | |
| $props = new stdClass(); | |
| $props->name = $row->Field; | |
| $props->type = $this->getTypeFromDbType($row->Type); | |
| $props->comment = $this->getCommentFromDbType($row->Type, $row->Null); | |
| yield $props; | |
| } | |
| } | |
| private function getTypeFromDbType(string $type) | |
| { | |
| switch ($type) { | |
| case 'blob': | |
| case 'tinyblob': | |
| case 'mediumblob': | |
| case 'longblob': | |
| case 'varbinary': | |
| case 'binary': | |
| case 'text': | |
| case 'tinytext': | |
| case 'mediumtext': | |
| case 'longtext': | |
| case 'time': | |
| case 'date': | |
| case 'datetime': | |
| case 'timestamp': | |
| case 'year': | |
| return 'string'; | |
| case 'bit': | |
| case 'bool': | |
| case 'boolean': | |
| return 'int'; | |
| default: | |
| // Fields with additional options | |
| if (preg_match('/^(float|decimal|dec|double)/', $type) == 1) { | |
| return 'float'; | |
| } | |
| if (preg_match('/^(tinyint|int|mediumint|smallint|integer|bigint|serial)/', $type) == 1) { | |
| return 'int'; | |
| } | |
| if (preg_match('/^(varchar|char|enum|set)/', $type) == 1) { | |
| return 'string'; | |
| } | |
| break; | |
| } | |
| } | |
| private function getCommentFromDbType(string $type, string $nullAllowed) | |
| { | |
| $format = []; | |
| $optionsLabel = 'size: '; | |
| switch ($type) { | |
| case 'time': | |
| $format[] = 'format: H:i:s'; | |
| break; | |
| case 'date': | |
| $format[] = 'format: Y-m-d'; | |
| break; | |
| case 'datetime': | |
| case 'timestamp': | |
| $format[] = 'format: Y-m-d H:i:s'; | |
| break; | |
| case 'year': | |
| $format[] = 'format: Y'; | |
| break; | |
| case 'bit': | |
| case 'bool': | |
| case 'boolean': | |
| break; | |
| default: | |
| if (preg_match('/^(enum|set)/', $type, $matches) == 1) { | |
| $optionsLabel = $matches[1] . ': '; | |
| } | |
| break; | |
| } | |
| if (preg_match_all('/\(([^\(]+)\)/', $type, $matches) == 1) { | |
| $format[] = $optionsLabel . $matches[1][0]; | |
| } | |
| if (preg_match('/unsigned/', $type) == 1) { | |
| $format[] = 'unsigned'; | |
| } | |
| $format[] = $nullAllowed == 'YES' ? 'Null Allowed' : 'Not Null'; | |
| return implode('; ', $format); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment