I am currently using an SQL Server 2000 used as a datasource for ODBC access, Testing PHP scripts from an Apache 2 server running on Windows 2000.
I was trying to get an image from the database using ODBC but the output always flushes automatically while I was just getting the result using odbc_result() function.
With this code, the picture automatically prints to the browser as soon as I hit odbc_result() (probably a bug, but bug reports aren't that easy to do).
<?php
$connH=odbc_pconnect("ImageDB","sa","",SQL_CUR_USE_IF_NEEDED) or die(odbc_errormsg());
$result=odbc_exec($connH, "SELECT Emp_Image FROM tblEmployeePics WHERE Emp_Id=547");
if ($result) {
odbc_longreadlen($result, 131072);
odbc_binmode($result,ODBC_BINMODE_PASSTHRU);
//upon calling this, the output flushes out to the browser... made me scratch
$m_FValue=odbc_result($result, 1);
}
?>
...after 48 hours of scratching I finally made a work around, but by using a function in the bin2hex() function documentation...
<?php
function hex2bin($data){
$len = strlen($data);
return pack("H" . $len, $data);
}
$connH=odbc_pconnect("ImageDB","sa","",SQL_CUR_USE_IF_NEEDED) or die(odbc_errormsg());
$result=odbc_exec($connH, "SELECT Emp_Image FROM tblEmployeePics WHERE Emp_Id=547");
if ($result) {
odbc_longreadlen($result, 131072);
odbc_binmode($result,ODBC_BINMODE_CONVERT);
$m_FValue=odbc_result($result, 1);
$out=hex2bin($m_FValue);
}
?>
The trick was to convert the output into hex by changing odbc_binmode to ODBC_BINMODE_CONVERT and using a handy function to convert it back to binary in order to facilitate manipulation of its size, depth etc...
odbc_binmode
(PHP 4, PHP 5)
odbc_binmode — Manejo de campos de datos binarios
Descripcion
(Elementos afectados ODBC SQL: BINARY, VARBINARY, LONGVARBINARY)
- ODBC_BINMODE_PASSTHRU: Paso a traves de datos binarios
- ODBC_BINMODE_RETURN: Devuelve como es
- ODBC_BINMODE_CONVERT: Devuelve convertido en caracter
Cuando los datos binarios en SQL son convertidos a datos caracter en C, cada byte (8 bits) de datos fuente es representada como dos caracteres en ASCII. Esos caracteres son la representacion en ASCII de los numeros en su forma Hexadecimal. Por ejemplo, un 00000001 binario es convertido a "01" y un 11111111 binario es convertido a "FF".
| modo binario | longreadlen | resultado |
|---|---|---|
| ODBC_BINMODE_PASSTHRU | 0 | passthru |
| ODBC_BINMODE_RETURN | 0 | passthru |
| ODBC_BINMODE_CONVERT | 0 | passthru |
| ODBC_BINMODE_PASSTHRU | 0 | passthru |
| ODBC_BINMODE_PASSTHRU | >0 | passthru |
| ODBC_BINMODE_RETURN | >0 | Devuleve como es |
| ODBC_BINMODE_CONVERT | >0 | Devuelve como caracter |
Si usamos odbc_fetch_into(), passthru significara que una cadena vacia es devuelta por esas campos.
Si result_id es 0, las definiciones se aplican por defecto para nuevos resultados.
Note: Por defecto, longreadlen es 4096 y el modo binario por defecto es ODBC_BINMODE_RETURN. El manejo de campos binarias largas tambien esta afectado por odbc_longreadlen()
odbc_binmode
11-Jan-2006 03:59
28-Apr-2003 05:27
Example: retrieve image from database.
<?php
$Link_ID = odbc_connect("DSN", "user", "pass");
$Query_ID = odbc_exec($Link_ID, "SELECT picture FROM categories");
// change to ODBC_BINMODE_CONVERT for comparison
odbc_binmode($Query_ID, ODBC_BINMODE_RETURN);
$Images = odbc_result($Query_ID, 1);
echo $Images;
?>
