value, and $args[0] must be // the associative array with all the name=>value placeholder mappings. // // If there was en error while substituting (e.g. type mismatch, // invalid key etc.), it inserts the plain error message into the // $tmpl, assigns it to $errormsg and returns false. Otherwise // returns the template after all substitutions. function sql_placeholder_ex($tmpl, $args, &$errormsg) { // Already compiled?.. If not, compile now. if (is_array($tmpl)) { $compiled = $tmpl; } else { $compiled = sql_compile_placeholder($tmpl); } list ($compiled, $tmpl, $has_named) = $compiled; // If there are at east one named placeholder, use first // function argument as replecement array. if ($has_named) $args = @$args[0]; // Make all the replacements. $p = 0; // scan position $out = ''; // resulting string $error = false; // was any error? foreach ($compiled as $num=>$e) { list ($key, $type, $start, $length) = $e; // Pre-string. $out .= substr($tmpl, $p, $start - $p); $p = $start + $length; $repl = ''; // replacement. $errmsg = ''; // error message on THIS substitution do { // Constant-style placeholder? if ($type === '#') { $repl = @constant($key); if (NULL === $repl) $error = $errmsg = "UNKNOWN_CONSTANT_$key"; break; } // Error handling. if (!isset($args[$key])) { $error = $errmsg = "UNKNOWN_PLACEHOLDER_$key"; break; } // Insert value corresponding to placeholder type. $a = $args[$key]; if ($type === '') { // Scalar-style placeholder. if (is_array($a)) { $error = $errmsg = "NOT_A_SCALAR_PLACEHOLDER_$key"; break; } $repl = "'".addslashes($a)."'"; break; } // Array or hash replacement. if (!is_array($a)) { $error = $errmsg = "NOT_AN_ARRAY_PLACEHOLDER_$key"; break; } if ($type === '@') { // List-style placeholder. foreach ($a as $v) $repl .= ($repl===''? "" : ",")."'".addslashes($v)."'"; } elseif ($type === '%') { // Hash-style placeholder. $lerror = array(); foreach ($a as $k=>$v) { if (!is_string($k)) { $lerror[$k] = "NOT_A_STRING_KEY_{$k}_FOR_PLACEHOLDER_$key"; } else { $k = preg_replace('/[^a-zA-Z0-9_]/', '_', $k); } $repl .= ($repl===''? "" : ", ").$k."='".@addslashes($v)."'"; } // On error makes the reeor message. if (count($lerror)) { $repl = ''; foreach ($a as $k=>$v) { if (isset($lerror[$k])) { $repl .= ($repl===''? "" : ", ").$lerror[$k]; } else { $k = preg_replace('/[^a-zA-Z0-9_-]/', '_', $k); $repl .= ($repl===''? "" : ", ").$k."=?"; } } $error = $errmsg = $repl; } } } while (false); if ($errmsg) $compiled[$num]['error'] = $errmsg; if (!$error) $out .= $repl; } $out .= substr($tmpl, $p); // If there was an error, re-make the resulting string // ass error message. if ($error) { $out = ''; $p = 0; // scan position foreach ($compiled as $num=>$e) { list ($key, $type, $start, $length) = $e; $out .= substr($tmpl, $p, $start - $p); $p = $start + $length; if (isset($e['error'])) { $out .= $e['error']; } else { $out .= substr($tmpl, $start, $length); } } // Last post-string. $out .= substr($tmpl, $p); $errormsg = $out; return false; } else { $errormsg = false; return $out; } } // function sql_placeholder(mixed $tmpl, $arg1 [,$arg2 ...]) // // Note: see description of sql_placeholder_ex() above. // // Returns the template after all substitutions or error message // prefixed with "ERROR: " string. // // If there was en error while substituting (e.g. type mismatch, // invalid key etc.), it inserts the plain error message into the // $tmpl and returns the string EXACTLY in form of: // "ERROR: template_with_error_messages". // It have to raise SQL error when try to execute the query. // You may also analyse the return value: if it starts with // "ERROR: ", the substitution have been aborted. // // Instead of using array as the second parameter, you may // pass all the arguments one by one. // // If there are at least one named placeholder in the template, // function must take exactly two arguments, and $arg1 must be // the associative array with all the name=>value placeholder // mappings. function sql_placeholder() { $args = func_get_args(); $tmpl = array_shift($args); $result = sql_placeholder_ex($tmpl, $args, $error); if ($result === false) return PLACEHOLDER_ERROR_PREFIX.$error; else return $result; } // function sql_pholder(mixed $tmpl, $arg1 [,$arg2 ...]) // // Note: see description of sql_placeholder_ex() above. // // Returns the template after all substitutions or error message // prefixed with "ERROR: " string. // // Instead of using array as the second parameter, you may // pass all the arguments one by one. // // If there are at least one named placeholder in the template, // function must take exactly two arguments, and $arg1 must be // the associative array with all the name=>value placeholder // mappings. function sql_pholder() { $args = func_get_args(); $tmpl = array_shift($args); $result = sql_placeholder_ex($tmpl, $args, $error); if ($result === false) { $error = "Placeholder substitution error. Diagnostics: \"$error\""; if (function_exists("debug_backtrace")) { $bt = debug_backtrace(); $error .= " in ".@$bt[0]['file']." on line ".@$bt[0]['line']; } trigger_error($error, E_USER_WARNING); return false; } return $result; } // No newline or space after that! ?>