只需几句话来解释我想做什么。
我想用能够调用存储过程的函数扩展我的lib。我在这里找到了制作它的步骤,但我很难将其设为泛型。
为了达到这个目的,我已经读过我必须在mysqli_stmt_bind_param上使用call_user_func_array,因为我只知道执行时参数IN的数量,类型和OUT的数量
以下是我所做的一些细节:
这里是代码的主要部分:
function executeProc($sProcName, $sInParamTypes, $aInParam, $iNumberParameterOut=0)
{
$oConnection = @mysqli_connect(DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DBNAME);
mysqli_set_charset($oConnection, "utf8");
/* code to build the $sCallStr */
$oMysqlCall = mysqli_prepare($oConnection, $sCallStr);
array_unshift($aFunctionParam, $oMysqlCall, $sInParamTypes);
$aFunctionParam = array_merge($aFunctionParam, $aInParam);
call_user_func_array("mysqli_stmt_bind_param", $aFunctionParam);
mysqli_stmt_execute($oMysqlCall);
}
call_user_func_array的返回值为NULL。我试着把这个函数称为manualy:
mysqli_stmt_bind_param($aFunctionParam[0], $aFunctionParam[1], $aFunctionParam[2], $aFunctionParam[3], $aFunctionParam[4], $aFunctionParam[5], $aFunctionParam[6], $aFunctionParam[7]);
它有效。我在DB中看到结果,并且函数的返回为TRUE。 有人可以帮忙吗?是否有另一种传递参数数组的方法? (比如参考?)
非常感谢您的帮助
答案 0 :(得分:0)
您可以使用...
使用"Argument unpacking":
mysqli_stmt_bind_param($oMysqlCall, $sInParamTypes, ...$aInParam);
这适用于引用传递的变量,无需使用array_unshift()
和array_merge()
来构建参数。
示例:
function foo(&$a, &$b, &$c) { var_dump($a,$b,$c); }
这将有效:
$arr = [1,2,3];
foo(...$arr); // Works
但这会产生警告:
$arr = [1,2,3];
call_user_func_array('foo', $arr);
// Warning: Parameter 1 to foo() expected to be a reference, value given
答案 1 :(得分:0)
以下是对我的问题的反馈:
我已经在您的帮助和帖子https://stackoverflow.com/a/48128540/6050817的帮助下完成了我的功能,并且效果很好。
我想发布我要分享的complet代码。此函数执行存储过程并收集此过程选择的所有数据和所有输出参数
function executeProc($sProcName, $sInParamTypes = "", $aInParam = null, $iNumberParameterOut=0)
{
global $oError;
$oError = false;
$aRows = array();
$sCallStr = "";
$sSelectOutParam = "";
$aReturn = array();
if($aInParam == null)
{
$aInParam = array();
}
$iLevel = error_reporting(9);
// open connection to DB
$oConnection = @mysqli_connect(DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DBNAME);
if ($oConnection === false)
{
$oError = mysqli_error($oConnection);
return false;
}
// we set the character set
mysqli_set_charset($oConnection, "utf8");
// we build the call to the stored procedure
$sCallStr = "CALL ";
$sCallStr = $sCallStr.$sProcName."(";
// we add the IN parameters
foreach($aInParam AS $sParam)
{
$sCallStr = $sCallStr."?,";
}
// we add the OUT parameters (since we can't access directly the out parameters, we store their value in variables @ on the DB) we will access theme at the end
for($iIndex=0; $iIndex<$iNumberParameterOut; $iIndex++)
{
$sSelectOutParam = $sSelectOutParam."@outParam".$iIndex.",";
}
// we remove the unwanted coma
if($iNumberParameterOut > 0)
{
$sSelectOutParam = rtrim($sSelectOutParam, ",");
}
else
{
$sCallStr = rtrim($sCallStr, ",");
}
// we merge the two parameters string and add the final parenthesis
$sCallStr = $sCallStr.$sSelectOutParam.")";
// we prepare the call
$oMysqlCall = mysqli_prepare($oConnection, $sCallStr);
// only if we have parameters we bind the call with the types and the list of IN parameters. If no parameters is waited by the stored procedure we don't need to bind
if(count($aInParam) > 0)
{
mysqli_stmt_bind_param($oMysqlCall, $sInParamTypes, ...$aInParam);
}
// we execute the stored procedure
mysqli_stmt_execute($oMysqlCall);
// we get the data that would be returned by select in the procedure
while ($oResult = mysqli_stmt_get_result($oMysqlCall))
{
if (mysqli_num_rows($oResult) > 0)
{
while ($oRow = mysqli_fetch_assoc($oResult))
{
foreach($oRow as $key => $val)
{
$aRows[$key] = $val;
}
$aReturn[] = $aRows;
$aRows = array();
}
}
// we free the return variable
mysqli_free_result($oResult);
// we get the next return
mysqli_stmt_next_result($oMysqlCall);
}
// we have to close the call to get the out parameters
mysqli_stmt_close($oMysqlCall);
if($iNumberParameterOut > 0)
{
// to get the out parameters stored in variables we have to make a select on on the DB
$oResult = mysqli_query($oConnection, "SELECT ".$sSelectOutParam.";");
// for every variable we create a row and add to an array
for($iIndex=0; $iIndex<$iNumberParameterOut; $iIndex++)
{
$iReturnIndex = 0;
while($oRow = mysqli_fetch_assoc($oResult))
{
if ($oRow===false) $oRow = array();
$aRows[key($oRow)] = $oRow[key($oRow)];
$iReturnIndex++;
}
if ($oRow===false && $iReturnIndex==0)
{
$aRows[0] = array();
}
}
// stored in the out key of our main return variable
$aReturn["out"] = $aRows;
}
// we free the rest
mysqli_free_result($oResult);
mysqli_close($oConnection);
error_reporting($iLevel);
// and return the data
return $aReturn;
}
}
希望这能有所帮助。随意评论或询问您是否理解某事