"integer", "f" => "double", "s" => "string" ); $fmt = str_split($args[0]); $argi = 1; $percent = false; $result = ""; foreach ($fmt as $c) { if ($percent) { /* First, validate the input. */ switch ($c) { case "%": break; case "d": case "f": case "s": if ($argi >= count($args)) throw new Exception("Too few arguments ({$argi}) for format string {$fmt}"); $arg = $args[$argi]; $argtype = gettype($arg); if ($argtype != $allowed_types[$c]) throw new Exception("Expected {$allowed_types[$c]} for argument {$argi}, but got {$argtype}"); $argi++; break; default: throw new Exception("Invalid format string: {$fmt}"); } /* Then, process it. */ switch ($c) { case "%": $result .= "%"; case "d": case "f": $result .= $arg; break; case "s": $result .= "'".mysql_real_escape_string($arg)."'"; break; default: assert(false); } $percent = false; } elseif ($c == "%") { $percent = true; } else { $result .= $c; } } if ($percent) throw new Exception("Invalid format string: {$fmt}"); return $result; } function test_mysql_printf() { assert("username='foo'" == mysql_printf("username=%s", "foo")); assert("username='foo\\'bar'" == mysql_printf("username=%s", "foo'bar")); assert("'\\\\''\\'''\\\"'" == mysql_printf("%s%s%s", "\\", "'", "\"")); assert("uid=12345" == mysql_printf("uid=%d", 12345)); assert("12345" == mysql_printf("%d%d%d%d%d", 1, 2, 3, 4, 5)); assert("'a''b''c'" == mysql_printf("%s%s%s", "a", "b", "c")); assert("balance=0.5" == mysql_printf("balance=%f", 1.0/2.0)); try { mysql_printf("uid=%d", "hello"); assert(false); } catch (Exception $e) { // ok } printf("+OK\n"); } test_mysql_printf(); ?>