使用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 相关文章推荐
简单实现限定phpmyadmin访问ip的方法
Mar 05 PHP
探讨PHP调用时间格式的参数详解
Jun 06 PHP
php导出csv格式数据并将数字转换成文本的思路以及代码分享
Jun 05 PHP
PHP清除数组中所有字符串两端空格的方法
Oct 20 PHP
Nginx服务器上安装并配置PHPMyAdmin的教程
Aug 18 PHP
PHP 下载文件时如何自动添加bom头及解释BOM头和去掉bom头的方法
Jan 04 PHP
PHP页面输出时js设置input框的选中值
Sep 30 PHP
php微信开发之音乐回复功能
Jun 14 PHP
PHP观察者模式示例【Laravel框架中有用到】
Jun 15 PHP
PHP基于cookie实现统计在线人数功能示例
Jan 16 PHP
PHP文件类型检查及fileinfo模块安装使用详解
May 09 PHP
laravel框架数据库操作、查询构建器、Eloquent ORM操作实例分析
Dec 20 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
Win2000+Apache+MySql+PHP4+PERL安装使用小结
2006/10/09 PHP
php 采集书并合成txt格式的实现代码
2009/03/01 PHP
php输出表格的实现代码(修正版)
2010/12/29 PHP
zf框架的zend_cache缓存使用方法(zend框架)
2014/03/14 PHP
利用jquery的获取JS文件中的字符串内容
2012/02/14 Javascript
JavaScript中的ArrayBuffer详细介绍
2014/12/08 Javascript
超赞的动手创建JavaScript框架的详细教程
2015/06/30 Javascript
jQuery实现简单的列表式导航菜单效果代码
2015/08/31 Javascript
js+css实现select的美化效果
2016/03/24 Javascript
如何给ss bash 写一个 WEB 端查看流量的页面
2017/03/23 Javascript
详解AngularJS脏检查机制及$timeout的妙用
2017/06/19 Javascript
ES6正则表达式扩展笔记
2017/07/25 Javascript
基于vue.js中事件修饰符.self的用法(详解)
2018/02/23 Javascript
小程序实现自定义导航栏适配完美版
2019/04/02 Javascript
Vue入门学习笔记【基本概念、对象、过滤器、指令等】
2019/04/13 Javascript
详解VUE前端按钮权限控制
2019/04/26 Javascript
JavaScript数组排序功能简单实现
2020/05/14 Javascript
JS如何定义用字符串拼接的变量
2020/07/11 Javascript
浅谈实现在线预览PDF的几种解决办法
2020/08/10 Javascript
详解Python中contextlib上下文管理模块的用法
2016/06/28 Python
Python的Flask框架中的Jinja2模板引擎学习教程
2016/06/30 Python
linux环境下的python安装过程图解(含setuptools)
2017/11/22 Python
python+openCV利用摄像头实现人员活动检测
2019/06/22 Python
Python实现报警信息实时发送至邮箱功能(实例代码)
2019/11/11 Python
python查看矩阵的行列号以及维数方式
2020/05/22 Python
使用Python构造hive insert语句说明
2020/06/06 Python
Python实现播放和录制声音的功能
2020/08/12 Python
Python如何使用vars返回对象的属性列表
2020/10/17 Python
文明礼仪伴我行演讲稿
2014/05/12 职场文书
企业承诺书格式
2014/05/21 职场文书
学生党员公开承诺书
2014/05/28 职场文书
网球场地租赁协议范本
2014/10/07 职场文书
2015年试用期工作总结
2014/12/12 职场文书
又涨知识了,自律到底多重要?
2019/06/27 职场文书
Golang的继承模拟实例
2021/06/30 Golang
vue中的可拖拽宽度div的实现示例
2022/04/08 Vue.js