It has come down from high places that a webapp I’ve been working on needs to move to stored procedures for everything it does in the database. To that end, I have taken to enforcing that constraint by writing a new database layer on top of mysqli which exposes only the “allowed” behavior. Consider what I have so far:
class Cas_Database
{
private $mysqli;
private $mode;
public function __construct(...)
{
... //Ommitted
}
public function Transaction(/* callable */ $func)
{
$mysqli->autocommit(false);
try
{
$func($this);
$mysqli->commit();
$mysqli->autocommit(true);
}
catch (Exception $ex)
{
$mysqli->rollback();
$mysqli->autocommit(true);
throw $ex;
}
}
public function MultiProcedure($schema, $func)
{
$args = func_num_args() - 2;
$sql = "CALL `{$this->mode}_{$schema}`.`{$func}` (";
if ($args >= 1)
{
$sql .= '? ';
for ($idx = 1; $idx < $args; ++$idx)
{
$sql .= ', ?';
}
}
$sql .= ')';
$stmt = $mysqli->prepare($sql);
$typeStr = '';
$refArgs = array(null);
for ($idx = 0; $idx < $args; ++$idx)
{
$argIndex = $idx + 2;
$arg = func_get_arg($argIndex);
$refArgs[] = &$arg;
if (is_int($arg))
{
$typeStr .= 'i';
}
else if (is_float($arg))
{
$typeStr .= 'f';
}
else
{
$typeStr .= 's';
}
}
$refArgs[0] = $typeStr;
call_user_func_array(array($stmt, 'bind_param'), $refArgs);
if ($stmt->execute() !== true)
{
$error = $stmt->error;
$stmt->close();
throw new Exception($error);
}
$mysqlAnswer = $stmt->get_result();
$results = array();
while (($answerRow = $mysqlAnswer->fetch_assoc()) !== null)
{
$results[] = $answerRow;
}
$stmt->close();
return $results;
}
}
Note how the MultiProcedure function expects multiple arguments from the user. Is there a way to specify that in the contract of the function so that users know what to look for, or are they forced to read the method to find out?
Use phpDocumentor’s
@paramsyntax to mention it in the documentation of the method. It will show up when you generate the docs, and in the developer’s IDE at the time the method will be used.Write the parameter name as
$paramn,...and in the description write that there can be any number of arguments.