【ecmall】数据模型部分增加执行存储过程功能
ecmall是MVC模式,其中M(模型)部分,在使用过程中发现没有执行存储过程的功能,所以自己在根文件中添加执行SP的功能。
我们从最底层的文件,一步一步往外层跳。
1.eccore/model/mysql.php
这是整个mvc模型部分最底层的支撑型文件了,封装了如何和mysql数据库交互的底层类和函数。
/**
* 执行存储过程
*
* @author Zheng Shou Chao
* @param string $sp_name存储过程名称
* @param array $in_args输入参数列表
* @param array $out_args输出参数列表
* @return bool
*/
function excute_sp($sp_name,$in_args,$out_args)
{
$sql=array();
$sql[0]='call '.trim($sp_name).'(';
foreach($in_argsas$value)
{
$sql[0]=$sql[0].$value.',';
}
$sql[1]='select ';
foreach($out_argsas$value)
{
$sql[0]=$sql[0].$value.',';
$sql[1]=$sql[1].$value.',';
}
//判断,最后一位是否是","号,是则删除
if($sql[0][strlen($sql[0])-1]==',')
{
$sql[0]=substr($sql[0],0,-1);
}
$sql[0]=$sql[0].')';
if($sql[1][strlen($sql[1])-1]==',')
{
$sql[1]=substr($sql[1],0,-1);
}
var_export($sql[0]);var_export($sql[1]);
//判断是否需要重连
if($this->_link_id===NULL)
{
$this->connect($this->_settings['dbhost'],$this->_settings['dbuser'],$this->_settings['dbpw'],$this->_settings['dbname'],$this->_settings['charset'],$this->_settings['pconnect']);
$this->_settings=array();
}
$this->_query_count++;
if($this->_query_count<=99)
{
$this->query_log[]=$sql;
}
/*当当前的时间大于类初始化时间的时候,自动执行ping这个自动重新连接操作 */
if(PHP_VERSION>='4.3'&&time()>$this->starttime+1)
{
mysql_ping($this->_link_id);
}
//$sql = $this->prefix($sql); //处理表名前缀
$i=0;
while($i<2)
{
if(!($query=mysql_query($sql[$i],$this->_link_id)))
{
$errno=mysql_errno();
$error=mysql_error();
if(($errno==126||$errno==145||$errno==1062||$errno==1194||$errno==1034||$errno==1035)
&&$times==0&&(preg_match('/\'\.?\\\\?([\w_]+)\\\\?([\w_]+)\'/',$error,$match)!==false))
{
//echo "REPAIR TABLE$match[2]<br>";
/*如果错误类型为可修复,则尝试修复这个表*/
if(isset($match[2]))
{
mysql_query("REPAIR TABLE $match[2]");
$query=$this->query($sql,$type,1);
}
}
elseif($errno==2006)
{
$this->ErrorMsg();exit;
}
else
{
if($type!='SILENT')
{
$trace = debug_backtrace();
$msg ='MySQL Error['.mysql_errno($this->_link_id).']:'.mysql_error($this->_link_id)."\nMySQLQuery:".$sql;
$msg .="\nWrong File: ".$trace[0]['file']."[".$trace[0]['line']."]";
trigger_error($msg,E_USER_ERROR);
returnfalse;
}
}
}
/*记录sql log */
if(defined('DEBUG_MODE')&&(DEBUG_MODE&8)==8)
{
$logfilename=$this->root_path.'data/mysql_query_'.$this->_dbhash.'_'.date('Y_m_d').'.log';
$str=$sql."\n\n";
if(PHP_VERSION>='5.0')
{
file_put_contents($logfilename,$str, FILE_APPEND,LOCK_EX);
}
else
{
$fp= @fopen($logfilename,'ab+');
if($fp)
{
fwrite($fp,$str);
fclose($fp);
}
}
}
$i++;
}
returnmysql_fetch_array($query);
}
2.eccore/model/model.base.php
新增函数
/**
* 执行存储过程
*
* @author Zheng Shou Chao
* @param string $sp_name存储过程名称
* @param array $in_args输入参数列表
* @param array $out_args输出参数列表
* @return bool
*/
function excuteSp($sp_name,$in_args,$out_args)
{
return$this->db->excute_sp($sp_name,$in_args,$out_args);
}
3.在自己的app文件中调用,我这里是admin/app/supplier.app.php
注意:定义输入参数时候,如果是字符串,要加’’两个单引号;输出参数要前面加@符号。
$in_args=array(
0=>'\'用户名\'',
1=>'\'密码\'',
2 =>'\'供应商名称\'',
3 =>12.11113,
4 =>89.23456,
);
$out_args=array(
0=>'@error',
);
$this->SupplierMode=& m('supplier');
$res=$this->SupplierMode->excuteSp('add_supplier',$in_args,$out_args);
$err='';
if($res['@error']){
$err='add_ok';
}
else{
$err='add_failed:'.$res;
}
其中excuteSp就是最外层的执行sp的封装函数了,输入sp的名称'add_supplier'以及输入和输出参数,就可以执行,执行结果是返回值$res,$res['@error']就是输出参数返回的值。实际是执行了如下sql语句:
call add_supplier('用户名','密码','供应商名称',12.11113,89.23456,@error);
select @error;