见世界

CodeIgniter Model自动生成

新生成的model : Friends.php

<?php
class Friends extends CI_Model
{
private $ID;
private $rid;
private $frid;
private $gid;
private $source;
private $status;
private $crdt;
private $updt;

public $table_name = 'fs_friends';

private $debug = TRUE;

//
private $mod_params = array();
private $results = array();
private $results_count = 0;

//
function __construct()
{
    parent::__construct();
    $this-&gt;load-&gt;database();
    $this-&gt;load-&gt;helpers('memcache');
}

function create($para=array())
{
    //sql
    $ksql = '';
    $vsql = '';
    foreach ($para as $key =&gt; $val)
    {
        $ksql .= $key. ',';
        $vsql .= '\'' . $val . '\',';
    }
    $ksql = rtrim($ksql , ',');
    $vsql = rtrim($vsql , ',');
    //sql
    $sql =  'INSERT INTO '. $this-&gt;table_name .'(' . $ksql .') ';
    $sql .=    'VALUES('.$vsql.')';

    if($this-&gt;debug)
    {
        echo  '&lt;hr&gt;';
        echo $sql;
        echo  '&lt;hr&gt;';
    }

    $ret = $this-&gt;db-&gt;query($sql);
    if(! $ret)
    {
        return FALSE;
    }
    else
    {
        return $this-&gt;db-&gt;insert_id();
    }
}

function Modify()
{
    $sql = 'UPDATE '. $this-&gt;table_name .' SET ';
    $count = 0;
    foreach ($this-&gt;mod_params as $key =&gt; $value)
    {
        if ($count &gt; 0)
            $sql = $sql . ', ';

        if (is_string($value) == TRUE)
            $sql = $sql . $key . '= \'' . $value . '\' ';
        else
            $sql = $sql . $key . '=' . $value;

        $count = $count + 1;
    }
    $sql = $sql . ', updt = ' . time() ;
    $sql = $sql . ' WHERE ID = ' . $this-&gt;ID;
    if($this-&gt;db-&gt;query($sql))
        return $this-&gt;db-&gt;affected_rows();
    else
        return FALSE;
}

// retrieve
function Retrieve($ID)
{
    $sql = 'SELECT * FROM '. $this-&gt;table_name .' WHERE ID = ' . $ID ;
    $query = $this-&gt;db-&gt;query($sql);
    if($query)
        return $query-&gt;row_array();
    else
        return FALSE;
}

function GetResultArray()   { return($this-&gt;results); }
function GetResultCount()   { return($this-&gt;results_count); }
function GetModParams()     { return($this-&gt;mod_params); } 

/* get prop */
function GetID()            { return $this-&gt;ID; }
function GetRid()            { return $this-&gt;rid; }
function GetFrid()            { return $this-&gt;frid; }
function GetGid()            { return $this-&gt;gid; }
function GetSource()            { return $this-&gt;source; }
function GetStatus()            { return $this-&gt;status; }
function GetCrdt()            { return $this-&gt;crdt; }
function GetUpdt()            { return $this-&gt;updt; }

/*set props */
function SetID($val, $ignore_mod=false)  { if ($ignore_mod != TRUE) $this-&gt;mod_params['ID'] = $val; $this-&gt;ID = $val;  }
function SetRid($val, $ignore_mod=false)  { if ($ignore_mod != TRUE) $this-&gt;mod_params['rid'] = $val; $this-&gt;rid = $val;  }
function SetFrid($val, $ignore_mod=false)  { if ($ignore_mod != TRUE) $this-&gt;mod_params['frid'] = $val; $this-&gt;frid = $val;  }
function SetGid($val, $ignore_mod=false)  { if ($ignore_mod != TRUE) $this-&gt;mod_params['gid'] = $val; $this-&gt;gid = $val;  }
function SetSource($val, $ignore_mod=false)  { if ($ignore_mod != TRUE) $this-&gt;mod_params['source'] = $val; $this-&gt;source = $val;  }
function SetStatus($val, $ignore_mod=false)  { if ($ignore_mod != TRUE) $this-&gt;mod_params['status'] = $val; $this-&gt;status = $val;  }
function SetCrdt($val, $ignore_mod=false)  { if ($ignore_mod != TRUE) $this-&gt;mod_params['crdt'] = $val; $this-&gt;crdt = $val;  }
function SetUpdt($val, $ignore_mod=false)  { if ($ignore_mod != TRUE) $this-&gt;mod_params['updt'] = $val; $this-&gt;updt = $val;  }

}
生成脚本,以及配套使用的pdo中间层: init.php

<?php
/*

  • @author: dlad@wobu2.com
  • @param: $tName, $cName
    *
  • @desc:生成通用的model代码,tableName,className以get形式传入
    *
  • @e.g.: 访问页面
  • http://domain/init.php?t=ms_msg_unread&c=MsgUnread
    */
    require_once(‘db.php’);
    if(isset($_SERVER[‘CLIENTNAME’])) {
    $tName = $argv[1];
    $cName = $argv[2];
    } else {
    $tName = $_GET[‘t’];
    $cName = $_GET[‘c’];
    }

$db = new db();
$db->Enq(‘use wz_sns;’);
$sql = “desc $tName”;
$colInfo = $db->Eq($sql);

$rows = array();
$rows[] = ‘<?php’;
$rows[] = “class {$cName} extends CI_Model”;
$rows[] = ‘{‘;

foreach($colInfo as $col) {
$rows[] = “ private \${$col[‘Field’]};”;
}

$rows[] = ‘ ‘;
$rows[] = ‘ private $table_name = \’’ . $tName . ‘\’;’;
$rows[] = ‘ ‘;
$rows[] = ‘ private $debug = TRUE;’;
$rows[] = ‘ ‘;
$rows[] = ‘ //‘;
$rows[] = ‘ private $mod_params = array();’;
$rows[] = ‘ private $results = array();’;
$rows[] = ‘ private $results_count = 0;’;
$rows[] = ‘’;
$rows[] = ‘ //‘;
$rows[] = ‘ function construct()’;
$rows[] = ‘ {‘;
$rows[] = ‘ parent::
construct();’;
$rows[] = ‘ $this->load->database();’;
$rows[] = ‘ $this->load->helpers(\’memcache\’);’;
$rows[] = ‘ }’;
$rows[] = ‘ ‘;
$rows[] = ‘ function create($para=array())’;
$rows[] = ‘ {‘;
$rows[] = ‘ //sql’;
$rows[] = ‘ $ksql = \’\’;’;
$rows[] = ‘ $vsql = \’\’;’;
$rows[] = ‘ foreach ($para as $key => $val)’;
$rows[] = ‘ {‘;
$rows[] = ‘ $ksql .= $key. \’,\’;’;
$rows[] = ‘ $vsql .= \’\\’\’ . $val . \’\\’,\’; ‘;
$rows[] = ‘ }’;
$rows[] = ‘ $ksql = rtrim($ksql , \’,\’);’;
$rows[] = ‘ $vsql = rtrim($vsql , \’,\’);’;
$rows[] = ‘ //sql’;
$rows[] = ‘ $sql = \’INSERT INTO \’. $this->table_name .\’(\’ . $ksql .\’) \’; ‘;
$rows[] = ‘ $sql .= \’VALUES(\’.$vsql.\’)\’;’;
$rows[] = ‘ ‘;
$rows[] = ‘ if($this->debug)’;
$rows[] = ‘ {‘;
$rows[] = ‘ echo \’<hr>\’;’;
$rows[] = ‘ echo $sql; ‘;
$rows[] = ‘ echo \’<hr>\’;’;
$rows[] = ‘ }’;
$rows[] = ‘ ‘;
$rows[] = ‘ $ret = $this->db->query($sql);’;
$rows[] = ‘ if(! $ret)’;
$rows[] = ‘ {‘;
$rows[] = ‘ return FALSE;’;
$rows[] = ‘ }’;
$rows[] = ‘ else ‘;
$rows[] = ‘ {‘;
$rows[] = ‘ return $this->db->insert_id();’;
$rows[] = ‘ }’;
$rows[] = ‘ }’;
$rows[] = ‘ ‘;
$rows[] = ‘ function Modify()’;
$rows[] = ‘ {‘;
$rows[] = ‘ $sql = \’UPDATE \’. $this->table_name .\’ SET \’;’;
$rows[] = ‘ $count = 0;’;
$rows[] = ‘ foreach ($this->mod_params as $key => $value)’;
$rows[] = ‘ {‘;
$rows[] = ‘ if ($count > 0)’;
$rows[] = ‘ $sql = $sql . \’, \’;’;
$rows[] = ‘’;
$rows[] = ‘ if (is_string($value) == TRUE)’;
$rows[] = ‘ $sql = $sql . $key . \’= \\’\’ . $value . \’\\’ \’;’;
$rows[] = ‘ else’;
$rows[] = ‘ $sql = $sql . $key . \’=\’ . $value;’;
$rows[] = ‘’;
$rows[] = ‘ $count = $count + 1;’;
$rows[] = ‘ }’;
$rows[] = ‘ $sql = $sql . \’, updt = \’ . time() ;’;
$rows[] = ‘ $sql = $sql . \’ WHERE ID = \’ . $this->ID;’;
$rows[] = ‘ if($this->db->query($sql))’;
$rows[] = ‘ return $this->db->affected_rows();’;
$rows[] = ‘ else ‘;
$rows[] = ‘ return FALSE;’;
$rows[] = ‘ }’;
$rows[] = ‘ ‘;
$rows[] = ‘ // retrieve’;
$rows[] = ‘ function Retrieve($ID)’;
$rows[] = ‘ {‘;
$rows[] = ‘ $sql = \’SELECT * FROM \’. $this->table_name .\’ WHERE ID = \’ . $ID ;’;
$rows[] = ‘ $query = $this->db->query($sql);’;
$rows[] = ‘ if($query)’;
$rows[] = ‘ return $query->row_array();’;
$rows[] = ‘ else ‘;
$rows[] = ‘ return FALSE; ‘;
$rows[] = ‘ }’;
$rows[] = ‘ ‘;
$rows[] = ‘ function GetResultArray() { return($this->results); }’;
$rows[] = ‘ function GetResultCount() { return($this->results_count); }’;
$rows[] = ‘ function GetModParams() { return($this->mod_params); } ‘;
$rows[] = ‘ ‘;

$rows[] = ‘ / get prop /‘;
foreach($colInfo as $col) {
$forFunName = ucfirst($col[‘Field’]);
$rows[] = “ function Get{$forFunName}() { return \$this->{$col[‘Field’]}; }”;
}
$rows[] = ‘’;
$rows[] = ‘ /set props /‘;
foreach($colInfo as $col) {
$forFunName = ucfirst($col[‘Field’]);
$rows[] = “ function Set{$forFunName}(\$val, \$ignore_mod=false) { if (\$ignore_mod != TRUE) \$this->mod_params[‘{$col[‘Field’]}’] = \$val; \$this->{$col[‘Field’]} = \$val; }”;
}
$rows[] = ‘ ‘;
$rows[] = ‘}’;

//写入文件
$fh = fopen(“{$cName}.php”, ‘w’);
fwrite($fh, implode(“\n”, $rows));
fclose($fh);
db.php

<?php
/*

class db {
static protected $pdo;

function __construct() {
    $this-&gt;GetInstance();
}

//获取唯一的数据库连接对象
function GetInstance() {
    if (self::$pdo == null) {
        self::$pdo = new PDO(__DATABASE_DSN, __DATABASE_USER, __DATABASE_PW);
        self::$pdo-&gt;exec('SET NAMES UTF8');

// var_dump(“once”);
}

    return self::$pdo;
}

//执行sql语句,返回结果矩阵
function Eq($sql) {
    $res = self::$pdo-&gt;query($sql);
    //如果存在,打印错误信息
    $this-&gt;IsError();
    $res-&gt;setFetchMode(PDO::FETCH_ASSOC);
    return $res-&gt;fetchAll();
}

//执行sql语句,返回单行结果
function Eor ($sql) {
    $res = self::$pdo-&gt;query($sql);
    //如果存在,打印错误信息
    $this-&gt;IsError();
    $res-&gt;setFetchMode(PDO::FETCH_ASSOC);
    $data = $res-&gt;fetch();
    return $data;
}

//执行sql语句,返回单列结果
function Ec($sql) {
    $res = self::$pdo-&gt;query($sql);
    //如果存在,打印错误信息
    $this-&gt;IsError();
    $res-&gt;setFetchMode(PDO::FETCH_ASSOC);
    $data = $res-&gt;fetchAll(PDO::FETCH_COLUMN, 0);
    return $data;
}

//执行sql语句,返回数量(单个结果)
function Es($sql) {
    $res = self::$pdo-&gt;query($sql);
    //如果存在,打印错误信息
    $this-&gt;IsError();
    $res-&gt;setFetchMode(PDO::FETCH_NUM);
    $data = $res-&gt;fetch(PDO::FETCH_COLUMN);
    return $data;
}

//执行sql语句,返回影响行数
function Enq($sql) {
    $res = self::$pdo-&gt;exec($sql);
    //如果存在,打印错误信息
    $this-&gt;IsError();

    return $res;
}

//todo:貌似用不到啊,直接用pdo对象吧
//执行sql语句,返回影响行数
function ExecuteNoneQueryWithPrepare($sql) {

}

//调试信息,发布后可关闭
function IsError() {
    $errorCode = self::$pdo-&gt;errorCode();
    if($errorCode != '00000') {
        var_dump(self::$pdo-&gt;errorInfo());
        exit();
    }
}

//添加引号
function quote($var) {
    return self::$pdo-&gt;quote($var);
}

}
还有一个处理模版的perl脚本,作用是做掉init.php中“$rows[] = ‘ xxxxxxxxx’;”这种机械性的工作。
刚发现被自己的sync覆盖掉了(sync很靠谱,主要是刚入职没有公司域账号,后来切换时程序没有保存)。逻辑很简单,就是逐行修改,注意替换单引号和美元符号,生成后最好再使用语法高亮的编辑器肉眼检查一下。
===================失而复得的分割线==========================
2012年6月14日15:19:26
新电脑启用sync,居然找到了。果然靠谱,不枉信你这么多年。有个问题就是没有考虑数组$ar[‘name’]中的单引号,多的话加条规则吧。

#!/usr/bin/perl -w
use strict;

open SFH, ‘<s.php’;
open DFH, ‘>d.php’;

while(<SFH>) {
chomp $;
$
=~ s/\‘/\\‘/g;
$_ =~ s/‘/\‘/g;
my $line = ‘$rows[] = \’’ . $_ . ‘\’’ . “;\n”;

print DFH $line;

}

close DFH;
close SF;
===================失而复得的分割线==========================
其实这个需求很适合使用heredoc语法。
我在使用过程中发现一个无法回避的问题是:heredoc内部转义变量或heredoc同其他字符串变量连接,会消灭掉除heredoc中“可见”换行效果外的所有换行(测试中涉及文件换行主要使用双引号内的\n,chr(10),chr(13)和chr(10)chr(13))。
换句话说就是,不使用heredoc语法,输出文件能正常换行。
heredoc包含变量,则转义的变量中换行符失效;将heredoc和一个包含换行的字符串变量连接,变量中的换行符失效。
初步的结论是存储heredoc的变量不能简单当做字符串变量使用。
这算不算php的一个bug呢?还有待严谨设计的实验去证明。

======================忍不住要说的分割线==========================
我一直对oo持保留态度(博问)。认为复杂度低的情况引入oo弊大于利。
不止一次在博客微博甚至面试中吐槽。“这种工程技术,是为了让5w 年薪coder胜任20w年薪工作而设计的。”上文中“年薪”替换成“智商”也没问题。
这次项目使用CI框架,又见如此Model。
你说这一坨坨的set,get函数有神马用啊?
你当你是C艹啊?

团队协作嘛,统一标准的好处很明显。我不是也写了生成函数做这事儿了么。
不过还是希望今后php的程序之路中,能早日发现ORM不可替代的便利。