Why date and time values are returned differently?
In fact, this is only a setting.
When you use PDO_SQLSRV (as is mentioned in the documentation), date and time types (smalldatetime, datetime, date, time, datetime2, and datetimeoffset) are by default returned as strings. Neither the PDO::ATTR_STRINGIFY_FETCHES nor the PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE attribute has any effect. In order to retrieve date and time types as PHP DateTime objects, set the connection or statement attribute PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE to true (it is false by default).
When you use SQLSRV driver (again from the documentation), smalldatetime, datetime, date, time, datetime2, and datetimeoffset types will be returned as PHP DateTime objects. This behaviour can be changed by setting the 'ReturnDatesAsStrings'
option in the connection string or at the statement level.
$conn = sqlsrv_connect(
"192.168.1.102,1433",
array(
"ReturnDatesAsStrings"=>true,
"Database"=>"RF_User",
"UID"=>"rfo-gcp",
"PWD" => ""
)
);
Note that some of the features depend on the version of PHP Driver for SQL Server.
How to cast parameters values?
Using CAST()
and CONVERT()
functions in the statement and binding parameter value with string value should work. Of course, you can specify the parameter data type, when you bind a parameter.
For PDO_SQLSRV you should extended syntax for PDOStatement::bindParam().
For SQLSRV you may use the extended $params
syntax to specify the SQL Server data type, when you make a call to sqlsrv_query()sqlsrv_execute()
.
I'm able to reproduce this issue (PHP 7.1.12, PHP Driver for SQL Server 4.3.0+9904, SQL Server 2012) and the solution is to use:
$params = array($id, SQLSRV_PARAM_IN, null, SQLSRV_SQLTYPE_BINARY); // SQLSRV
$stmt->bindParam(1, $id, PDO::PARAM_LOB, null, PDO::SQLSRV_ENCODING_BINARY); // PDO_SQLSRV
Table:
CREATE TABLE tbl_rfaccount (id binary(13), birthdate datetime)
INSERT INTO tbl_rfaccount (id, birthdate) VALUES (CONVERT(binary(13), 'Test'), GETDATE())
PHP:
<?php
...
//
$id = "Test";
// SQLSRV
$tsql = "SELECT birthdate FROM tbl_rfaccount WHERE id = ?";
$params = array($id, SQLSRV_PARAM_IN, null, SQLSRV_SQLTYPE_BINARY);
$stmt = sqlsrv_query($conn, $tsql, $params);
if ($stmt === false) {
echo "Error (sqlsrv_query): ".print_r(sqlsrv_errors(), true);
exit;
}
$result = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
var_dump($result);
// PDO_SQLSRV
$tsql = "SELECT birthdate FROM tbl_rfaccount WHERE id = ?";
$stmt = $conn->prepare($tsql);
$stmt->bindParam(1, $id, PDO::PARAM_LOB, null, PDO::SQLSRV_ENCODING_BINARY);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
var_dump($result);
...
?>