使用PHP反射机制来构造"CREATE TABLE"的sql语句


Posted in PHP onMarch 21, 2019

反射是指在PHP运行状态中,扩展分析PHP程序,导出或提取出关于类、方法、属性、参数等的详细信息,包括注释。这种动态获取的信息以及动态调用对象的方法的功能称为反射API。反射是操纵面向对象范型中元模型的API,其功能十分强大,可帮助我们构建复杂,可扩展的应用。

其用途如:自动加载插件,自动生成文档,甚至可用来扩充PHP语言。

php反射api由若干类组成,可帮助我们用来访问程序的元数据或者同相关的注释交互。借助反射我们可以获取诸如类实现了那些方法,创建一个类的实例(不同于用new创建),调用一个方法(也不同于常规调用),传递参数,动态调用类的静态方法。

反射api是php内建的oop技术扩展,包括一些类,异常和接口,综合使用他们可用来帮助我们分析其它类,接口,方法,属性,方法和扩展。这些oop扩展被称为反射。

下面的程序使用Reflection来构造"CREATE TABLE"的sql语句。如果你不是很熟悉反射机制,可以从这个程序中看看反射的魅力与作用。

<?php
/**
 * Creates an SQL 'Create Table' based upon an entity
 * @author Chris Tankersley <chris@ctankersley.com>
 * @copyright 2010 Chris Tankersley
 * @package PhpORM_Cli
 */
class PhpORM_Cli_GenerateSql
{
  /**
   * Use a MySQL database
   */
  const MYSQL = 'mysql';
  /**
   * Use a SQLite database
   */
  const SQLITE = 'sqlite';
  /**
   * Types that are allowed to have a length
   * @var array
   */
  protected $_hasLength = array('integer', 'varchar');
  /**
   * Regexes needed to pull out the different comments
   * @var array
   */
  protected $_regexes = array(
    'type' => '/ type=([a-z_]*) /',
    'length' => '/ length=([0-9]*) /',
    'default' => '/ default="(.*)" /',
    'null' => '/ null /',
  );
  /**
   * Types that we support
   * @var array
   */
  protected $_validTypes = array(
    'boolean' => 'BOOL',
    'date' => 'DATE',
    'integer' => 'INT',
    'primary_autoincrement' => 'INT AUTO_INCREMENT PRIMARY KEY',
    'text' => 'TEXT',
    'timestamp' => 'TIMESTAMP',
    'varchar' => 'VARCHAR',
  );
  /**
   * Name of the class we will interperet
   * @var string
   */
  protected $_className;
  /**
   * Name of the table we are generating
   * @var string
   */
  protected $_tableName;
  /**
   * The type of database we are generating
   * @var string
   */
  protected $_type;
  /**
   * Sets the name of the class we are working with
   * @param string $class
   * @param string $table_name
   * @param string $type
   */
  public function __construct($class, $table_name, $type = self::MYSQL)
  {
    $this->_className = $class;
    $this->_tableName = $table_name;
    $this->_type = $type;
  }
  /**
   * Builds an SQL Line for a property
   * @param ReflectionProperty $property
   * @return string
   */
  protected function _getDefinition($property)
  {
    $type = '';
    $length = '';
    $null = '';
    preg_match($this->_regexes['type'], $property->getDocComment(), $matches);
    if(count($matches) == 2) {
      if(array_key_exists($matches[1], $this->_validTypes)) {
        $type = $this->_validTypes[$matches[1]];
        if(in_array($matches[1], $this->_hasLength)) {
          $length = $this->_getLength($property);
        }
        if($matches[1] != 'primary_autoincrement') {
          $null = $this->_getNull($property);
        }
        $sql = '`'.$property->getName().'` '.$type.' '.$length.' '.$null;
        return $sql;
      } else {
        throw new Exception('Type "'.$matches[1].'" is not a supported SQL type');
      }
    } else {
      throw new Exception('Found '.count($matches).' when checking Type for property '.$property->getName());
    }
  }
  /**
   * Extracts the Length from a property
   * @param ReflectionProperty $property
   * @return string
   */
  protected function _getLength($property)
  {
    preg_match($this->_regexes['length'], $property->getDocComment(), $matches);
    if(count($matches) == 2) {
      return '('.$matches[1].')';
    } else {
      return '';
    }
  }
  /**
   * Determines if a Property is allowed to be null
   * @param ReflectionProperty $property
   * @return string
   */
  protected function _getNull($property)
  {
    preg_match($this->_regexes['null'], $property->getDocComment(), $matches);
    if(count($matches) == 1) {
      return 'NULL';
    } else {
      return 'NOT NULL';
    }
  }
  /**
   * Generates a block of SQL to create a table from an Entity
   * @return string
   */
  public function getSql()
  {
    $class = new ReflectionClass($this->_className);
    $definitions = array();
    foreach($class->getProperties() as $property) {
      if(strpos($property->getName(), '_') === false) {
        $definitions[] = $this->_getDefinition($property);
      }
    }
    $columns = implode(",n", $definitions);
    $sql = "CREATE TABLE ".$this->_tableName." (".$columns.")";
    if($this->_type == self::MYSQL) {
      $sql .= " ENGINE=MYISAM";
    }
    return $sql.";";
  }
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。如果你想了解更多相关内容请查看下面相关链接

PHP 相关文章推荐
PHP网站基础优化方法小结
Sep 29 PHP
php若干单维数组遍历方法的比较
Sep 20 PHP
PHP数组 为文章加关键字连接 文章内容自动加链接
Dec 29 PHP
php中用socket模拟http中post或者get提交数据的示例代码
Aug 08 PHP
php获取文件大小的方法
Feb 26 PHP
zf框架的校验器InArray使用示例
Mar 13 PHP
ThinkPHP中公共函数路径和配置项路径的映射分析
Nov 22 PHP
Yii使用Captcha验证码的方法
Dec 28 PHP
php curl 模拟登录并获取数据实例详解
Dec 22 PHP
thinkPHP5.0框架安装教程
Mar 25 PHP
利用PHPStorm如何开发Laravel应用详解
Aug 30 PHP
基于PHP-FPM进程池探秘
Oct 17 PHP
启用OPCache提高PHP程序性能的方法
Mar 21 #PHP
Discuz不使用插件实现简单的打赏功能
Mar 21 #PHP
PHP+RabbitMQ实现消息队列的完整代码
Mar 20 #PHP
PHP实现的数据对象映射模式详解
Mar 20 #PHP
PHP单例模式数据库连接类与页面静态化实现方法
Mar 20 #PHP
PHP实现的策略模式示例
Mar 20 #PHP
PHP实现数组和对象的相互转换操作示例
Mar 20 #PHP
You might like
PHP多线程类及用法实例
2014/12/03 PHP
php实现的mongoDB单例模式操作类
2018/01/20 PHP
详解PHP版本兼容之openssl调用参数
2018/07/25 PHP
JQuery中对服务器控件 DropdownList, RadioButtonList, CheckboxList的操作总结
2011/06/28 Javascript
基于jquery的时间段实现代码
2012/08/02 Javascript
js Date概念详细介绍
2013/11/22 Javascript
js的Prototype属性解释及常用方法
2014/05/08 Javascript
zepto与jquery的区别及zepto的不同使用8条小结
2016/07/28 Javascript
基于JQuery及AJAX实现名人名言随机生成器
2017/02/10 Javascript
node下使用UglifyJS压缩合并JS文件的方法
2018/03/07 Javascript
微信小程序 textarea 层级过高问题简单解决方案
2019/10/14 Javascript
JavaScript计算出两个数的差值
2020/03/19 Javascript
通过实例解析javascript Date对象属性及方法
2020/11/04 Javascript
Python装饰器实现几类验证功能做法实例
2017/05/18 Python
利用python批量修改word文件名的方法示例
2017/10/17 Python
Python hexstring-list-str之间的转换方法
2019/06/12 Python
python循环输出三角形图案的例子
2019/11/22 Python
python GUI库图形界面开发之PyQt5动态加载QSS样式文件
2020/02/25 Python
解决Jupyter notebook更换主题工具栏被隐藏及添加目录生成插件问题
2020/04/20 Python
Python之字典添加元素的几种方法
2020/09/30 Python
HTML5 placeholder属性详解
2016/06/22 HTML / CSS
研究生自我鉴定范文
2013/10/30 职场文书
自荐信封面
2013/12/04 职场文书
商务英语大学生职业生涯规划书范文
2014/01/01 职场文书
工程管理专业毕业生自荐信
2014/01/24 职场文书
户外亲子活动策划方案
2014/02/07 职场文书
销售主管岗位职责
2014/02/08 职场文书
高中微机老师自我鉴定
2014/02/16 职场文书
2014年最新学习全国两会精神心得
2014/03/17 职场文书
结对共建工作方案
2014/06/02 职场文书
心理咨询专业自荐信
2014/07/07 职场文书
邀请函范文
2015/02/02 职场文书
2015秋季运动会通讯稿
2015/07/18 职场文书
社区干部培训心得体会
2016/01/06 职场文书
ConditionalOnProperty配置swagger不生效问题及解决
2022/06/14 Java/Android
win10电脑关机快捷键是哪个 win10快速关机的几种方法
2022/08/14 数码科技