--TEST-- Test for retrieving encrypted data of floats as output parameters --DESCRIPTION-- Use PDOstatement::bindParam with all PDO::PARAM_ types. This test generates input float. For your reference: https://en.wikipedia.org/wiki/Single-precision_floating-point_format#Precision_limitations_on_integer_values --ENV-- PHPT_EXEC=true --SKIPIF-- --FILE-- "An invalid PHP type was specified as an output parameter. DateTime objects, NULL values, and streams cannot be specified as output parameters."); $pdoParamTypes = array( PDO::PARAM_BOOL, // 5 PDO::PARAM_NULL, // 0 PDO::PARAM_INT, // 1 PDO::PARAM_STR, // 2 PDO::PARAM_LOB // 3 ); ////////////////////////////////////////////////////////////////////////////////// function printValues($msg, $det, $rand, $inputValues) { echo $msg; echo "input 0: "; var_dump($inputValues[0]); echo "fetched: "; var_dump($det); echo "input 1: "; var_dump($inputValues[1]); echo "fetched: "; var_dump($rand); } function testOutputFloats($fetchNumeric, $inout) { global $pdoParamTypes, $inputValues, $errors; try { $conn = connect(); $conn->setAttribute(PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, $fetchNumeric); $tbname = "test_floats_types"; $spname = "test_floats_proc"; $bits = array(1, 12, 24, 36, 53); foreach ($bits as $bit) { $type = "float($bit)"; trace("\nTesting $type:\n"); $inputValues = array(); // create random input values for ($i = 0; $i < 2; $i++) { $mantissa = rand(1, 10000000); $decimals = rand(1, 100); $floatNum = $mantissa + $decimals / 10000; if ($i > 0) { // make the second input negative $floatNum *= -1; } array_push($inputValues, $floatNum); } //create and populate table $colMetaArr = array(new ColumnMeta($type, "c_det"), new ColumnMeta($type, "c_rand", null, "randomized")); createTable($conn, $tbname, $colMetaArr); insertRow($conn, $tbname, array("c_det" => new BindParamOp(1, $inputValues[0], 'PDO::PARAM_INT'), "c_rand" => new BindParamOp(2, $inputValues[1], 'PDO::PARAM_INT')), "prepareBindParam"); // fetch with PDO::bindParam using a stored procedure $procArgs = "@c_det $type OUTPUT, @c_rand $type OUTPUT"; $procCode = "SELECT @c_det = c_det, @c_rand = c_rand FROM $tbname"; createProc($conn, $spname, $procArgs, $procCode); // call stored procedure $outSql = getCallProcSqlPlaceholders($spname, 2); foreach ($pdoParamTypes as $pdoParamType) { $det = 0.0; $rand = 0.0; $stmt = $conn->prepare($outSql); $len = 2048; if ($pdoParamType == PDO::PARAM_BOOL || $pdoParamType == PDO::PARAM_INT) { $len = PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE; $det = 0; $rand = 0; } trace("\nParam $pdoParamType with INOUT = $inout\n"); if ($inout) { $paramType = $pdoParamType | PDO::PARAM_INPUT_OUTPUT; } else { $paramType = $pdoParamType; } $stmt->bindParam(1, $det, $paramType, $len); $stmt->bindParam(2, $rand, $paramType, $len); try { $stmt->execute(); $errMsg = "****$type as $pdoParamType failed with INOUT = $inout:****\n"; if ($pdoParamType == PDO::PARAM_BOOL) { // for boolean values, they should all be bool(true) // because all floats are non-zeroes if (!$det || !$rand) { printValues($errMsg, $det, $rand, $inputValues); } } else { // Compare the retrieved values against the input values // if either of them is very different, print them all if (!compareFloats($inputValues[0], floatval($det)) || !compareFloats($inputValues[1], floatval($rand))) { printValues($errMsg, $det, $rand, $inputValues); } } } catch (PDOException $e) { $message = $e->getMessage(); $errMsg = "EXCEPTION: ****$type as $pdoParamType failed with INOUT = $inout:****\n"; if ($pdoParamType == PDO::PARAM_NULL || $pdoParamType == PDO::PARAM_LOB) { // Expected error IMSSP: "An invalid PHP type was specified // as an output parameter. DateTime objects, NULL values, and // streams cannot be specified as output parameters." $found = strpos($message, $errors['IMSSP']); if ($found === false) { printValues($errMsg, $det, $rand, $inputValues); } } else { printValues($errMsg, $det, $rand, $inputValues); } } } dropProc($conn, $spname); dropTable($conn, $tbname); } unset($stmt); unset($conn); } catch (PDOException $e) { echo $e->getMessage(); } } testOutputFloats(false, false); testOutputFloats(true, false); testOutputFloats(false, true); testOutputFloats(true, true); echo "Done\n"; ?> --CLEAN-- --EXPECT-- Done