使用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跨站刷票的实现代码
Jun 18 PHP
thinkphp实现面包屑导航(当前位置)例子分享
May 10 PHP
PHP实现的比较完善的购物车类
Dec 02 PHP
laravel容器延迟加载以及auth扩展详解
Mar 02 PHP
PHP模板引擎Smarty内建函数foreach,foreachelse用法分析
Apr 11 PHP
Yii2 assets清除缓存的方法
May 16 PHP
PHP中STDCLASS用法实例分析
Nov 11 PHP
php 解决扫描二维码下载跳转问题
Jan 13 PHP
PHP实现找出有序数组中绝对值最小的数算法分析
Aug 07 PHP
PHP中OpenSSL加密问题整理
Dec 14 PHP
PHP code 验证码生成类定义和简单使用示例
May 27 PHP
PHP替换Word中变量并导出PDF图片的实现方法
Nov 26 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检测文本的编码
2015/07/26 PHP
2款PHP无限级分类实例代码
2015/11/11 PHP
php 实现一个字符串加密解密的函数实例代码
2016/11/01 PHP
Symfony2针对输入时间进行查询的方法分析
2017/06/28 PHP
PHP程序守护进程化实现方法详解
2020/07/16 PHP
jquery ui resize 中border-box的bug修正
2015/04/26 Javascript
JavaScript中常见的字符串操作函数及用法汇总
2015/05/04 Javascript
jQuery+css3实现文字跟随鼠标的上下抖动
2015/07/31 Javascript
BootStrap创建响应式导航条实例代码
2016/05/31 Javascript
jQuery实现动态给table赋值的方法示例
2017/07/04 jQuery
JsonProperty 的使用方法详解
2019/10/11 Javascript
JS实现网页端猜数字小游戏
2020/03/06 Javascript
python判断端口是否打开的实现代码
2013/02/10 Python
仅用500行Python代码实现一个英文解析器的教程
2015/04/02 Python
Python简单实现TCP包发送十六进制数据的方法
2016/04/16 Python
Python注释详解
2016/06/01 Python
Python 使用with上下文实现计时功能
2018/03/09 Python
python 对给定可迭代集合统计出现频率,并排序的方法
2018/10/18 Python
Pandas过滤dataframe中包含特定字符串的数据方法
2018/11/07 Python
python实现连续图文识别
2018/12/18 Python
在python中使用requests 模拟浏览器发送请求数据的方法
2018/12/26 Python
浅谈Scrapy网络爬虫框架的工作原理和数据采集
2019/02/07 Python
python f-string式格式化听语音流程讲解
2019/06/18 Python
简单了解django索引的相关知识
2019/07/17 Python
Django接收post前端返回的json格式数据代码实现
2019/07/31 Python
scikit-learn线性回归,多元回归,多项式回归的实现
2019/08/29 Python
python画图常规设置方式
2020/03/05 Python
PyQt5结合matplotlib绘图的实现示例
2020/09/15 Python
css3实现简单的白云飘动背景特效
2020/10/28 HTML / CSS
SmartBuyGlasses意大利:购买太阳镜、眼镜和隐形眼镜
2018/11/20 全球购物
英国露营设备和户外服装购物网站:Simply Hike
2019/05/05 全球购物
美赞臣营养马来西亚旗舰店:Enfagrow马来西亚
2019/07/26 全球购物
建筑工程技术应届生自荐信
2013/09/27 职场文书
《乞巧》教学反思
2014/02/27 职场文书
老人节主持词
2015/07/04 职场文书
详解CSS开发过程中的20个快速提升技巧
2021/05/21 HTML / CSS