how to Read 10000+ bytes[] of binary data from DataBase? - php

I have one table that contains Company's Logo.... whenever I read small image like 4096 bytes It works perfectly, but i am not able to read over the 10000 bytes in php.
it's read only 4096 bytes from database
Update:
Column Lenth in Sql :
My Code in Model
function GetLogoById($Id)
{
$this->load->database();
mssql_query("SET TEXTSIZE 2147483647");
// or use CI's active record
$this->db->query("SET TEXTSIZE 2147483647");
$query = $this->db->query( "EXEC GetLogoById '$Id'" );
$result = array();
foreach ($query->result() as $row)
{
$result[] = array("Logo"=> $row->Logo);
}
return $result;
}
My Controller Code :
public function GetLogoById()
{
parse_str($_SERVER['QUERY_STRING'],$_GET);
$Id = $_GET['Id'];
$this->load->model('MyModel');
$result = $this->MyModel->GetLogoById($Id);
header('Content-type: image/png');
echo $result[0]['Logo'];
}
I am Getting Only 4096 bytes like :(string:4096) ����
I am getting this error on browser :

I think this is a problem with using MSSQL where data stored in a text type column is truncated for no apparent reason after 4096 characters.
Increase the maximum size of a text column to be returned from SQL Server. You can do this with the following SQL query:
SET TEXTSIZE 2147483647
You can run this with the following PHP, run it right after you make the connection:
mssql_query("SET TEXTSIZE 2147483647");
// or use CI's active record
$this->db->query("SET TEXTSIZE 2147483647");
And another way way to work around the issue is to change the "textlimit" and "textsize" settings within php.ini, like the following:
mssql.textlimit = 2147483647
mssql.textsize = 2147483647
Refer to this SO answer Why TEXT column returns only 4096 bytes? which refers to SQL Server, PHP and Truncating Text.
Update: Upon further review, reading this PHP bug, you may want to try using PDO_ODBC to connect to MSSQL Server instead:
//$dsn = 'mssql:host=MYBOX;dbname=testdb';
$dsn = 'odbc:DRIVER={SQL Server};SERVER=MYBOX;DATABASE=testdb;';
Also try setting the TEXTSIZE to megabytes:
$sql = "SET TEXTSIZE 3145728"; // 3 Megabytes
mssql_query($sql, $db) or die(mssql_get_last_message());

Got solution with sqlsrv driver ;)
function GetLogoById($Id)
{
$serverName = "XXXXX";
$uid = "XXXXXX";
$pwd = "XXXXXX";
$connectionInfo = array( "UID"=>$uid,
"PWD"=>$pwd,
"Database"=>"XXXXXX");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
$tsql = "select Logo from TableName where Id = '$Id'";
$stmt = sqlsrv_query( $conn, $tsql);
if( $stmt === false)
{
echo "Error in query preparation/execution.\n";
die( print_r( sqlsrv_errors(), true));
}
/* Retrieve each row as an associative array and display the results.*/
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC))
{
return $row;
}
/* Free statement and connection resources. */
sqlsrv_free_stmt( $stmt);
sqlsrv_close( $conn);
}

First. don't use the DBMS to store images. trust me.
Second, don't use the DMBS to store the images.....
Now, if you are getting an $id from the model, why have looping code to return an array? kind of defeats the purpose of an id?
I assume that the logo data is stored in the form of a BLOB ?
If this is the case the model could be something like:
$query = $this->db->get_where('tablename',array('id' => $id));
if ($query->num_rows() == 1)
{
return $query->first_row()->logo
}
else
{
return FALSE;
}
then the controller code could be something like:
public function GetLogoById($id)
{
$this->load->model('MyModel');
if($logo = $this->MyModel->GetLogoById($id))
{
$this->output->set_content_type('image/png');
$this->output->set_output($logo);
}
}

Related

how do i create a php function to echo out mysql data, a function that can be reused?

I need to write a PHP function to echo out MySQL rows as I give it the SQL query I want to be executed as the function argument. I have tried out the following code but it is giving me an undefined index error
function runQuery($query) {
$conn = mysqli_connect('localhost', 'root', '', 'mydb');
$result = mysqli_query($conn,$query);
while($row=mysqli_fetch_assoc($result)) {
$resultset[] = $row;
}
if(!empty($resultset))
return $resultset;
the code I am using to call the function is;
runQuery(SELECT * FROM mytable WHERE id='5')
echo $resultset['name'];
this, however, gives me this error, undefined index 'resultset' on line 25. any kind assistance would be appreciated
You dont have a $resultset in the scope of where you call the function. The function creates one, but that is only visible inside the function.
You will also have to put QUOTES around the query, you are passing a string there so it needs to be quoted.
Your errors should have generated quite a few error messages, if you were not getting them I have added 4 lines of code you should add while testing code for example if you are testing on a LIVE server with error reporting turned off.
You should also change the function to ensure you always return something
So amend the call to
ini_set('display_errors', 1);
ini_set('log_errors',1);
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
function runQuery($conn, $query) {
$resultset = [];
$result = mysqli_query($conn,$query);
while($row=mysqli_fetch_assoc($result)) {
$resultset[] = $row;
}
return $resultset;
}
$resultset = runQuery($conn, "SELECT * FROM mytable WHERE id='5'");
// as result will now be a multidimentional array
// you will need to loop over that to get each returned row
foreach ( $resultset as $row ) {
echo $row['name'];
}
AFTER your edit there is another error
$conn is not created inside the function, so will be invisible in the function code unless passed as a parameter to the function (there is another way but lets not get into the bad habit of using global variables)
First, your code is probably vulnerable to SQL Injection. Please take care of that, by using prepared statements for instance.
https://www.w3schools.com/sql/sql_injection.asp
https://websitebeaver.com/prepared-statements-in-php-mysqli-to-prevent-sql-injection
Other than that, you do not assign the return value of your function to a variable. You cannot use the $resultset defined in the function scope outside the function, as it is a different scope. Try the following:
$resultset = runQuery("SELECT * FROM mytable WHERE id='5'")
echo $resultset['name'];
I built a similar function recently - here is my code
function returnSQL($conn, $nameSql) {
$result = mysqli_query($conn, $nameSql);
if (!$result) {
return 0;
}
while ($res = mysqli_fetch_assoc($result)) {
$data[] = $res;
}
return $data;
}
The connection is setup outside the function and passed in as an argument along with the sql like this...
$conn = mysqli_connect($servername, $username, $password, $DBName);
if (!$conn) {
echo 'Failed to connect to database :- ' . $DBName . '<br>';
die();
}
$sql = "SELECT * FROM table";
$data = returnSQL($conn, $sql);
I'm no expert, but this works for me :)
What I notice from your code is that you are trying to access $resultset outside of the function it is declared in and I think it is not available as a global variable - perhaps it should be something like:
$returnValue = runQuery(SQL statement);
// $returnValue is assigned the array returned from runQuery()
echo $returnValue['name'];

PHP mysqli_fetch_assoc not doing returning correct value

I have an old PHP code that has mysql in it.
It gets an array from a SELECT statement, adds it to a JSON object, as a property and echoes the encoded JSON.
I changed it around to use mysqli, but when I try to get the rows, and create an array out of them, it just returns nothing.
Here's the old mysql code:
$con = mysql_connect('host','account','password');
if (!$con)
{
//log my error
};
mysql_select_db("database_name", $con);
mysql_set_charset('utf8');
$sql = "SELECT field1 as Field1, field2 as Field2 from table where ID = '".$parameter."'";
$query = mysql_query($sql);
$results = array();
while($row = mysql_fetch_assoc( $query ) )
{
$results[] = $row;
}
return $results;
Version1: Here's the new one that I tried writing:
$con = mysqli_connect('host','account','password','database_name');
$sql = "SELECT field1 as Field1, field2 as Field2 from table where ID = '".$parameter."'";
$results = array();
if($result=mysqli_query($con, $sql))
{
while ($row=mysqli_fetch_assoc($result))
{
$results[] = $row;
}
return $results;
}
else
{
//error
}
Version2: Second thing I tried, which only returns 1 ROW:
...same as above until $sql
if($result=mysqli_query($con,$sql))
{
$row=mysqli_fetch_assoc($result);
return $row;
}
Version3: Or I tried to completely mirror the mysql structure like this:
$sql = "SELECT ...";
$query = mysqli_query($con, $sql);
$results = array();
while($row = mysqli_fetch_assoc( $query ) )
{
$results[] = $row;
}
return $results;
Wrapping the resulting array into the JSON:
$obj = new stdClass();
$obj->Data = $results;
$obj->ErrorMessage = '';
die(json_encode($obj)); //or echo json_encode($obj);
None of the mysqli version are working, so I was thinking there might be an important change in the way these arrays are created.
Any tips on what could be wrong on the first mysqli example?
With Version2 I can tell that the SQL connection is there, and I can at least select a row. But it's obviously only one row, than it returns it. It makes me think, that building up the array is the source of the problem, or it's regarding the JSON object...
LATER EDIT:
OK! Found a working solution.
ALSO, I played around with the data, selected a smaller chunk, and it suddenly worked. Lesson from this: the function is not responding the same way for 40 rows or for 5 rows. Does it have something to do with a php.ini setting? Or could there be illegal characters in the selection? Could it be that the length of a 'Note' column (from the db) is too long for the array to handle?
Here's the working chunk of code, that selects some rows from the database, puts them into an array, and then puts that array into an object that is encoded into JSON at the end, with a statusmessage next to it. Could be improved, but this is just for demo.
$con = mysqli_connect('host','username','password','database_name');
if (!$con)
{
$errorMessage = 'SQL connection error: '.$con->connect_error;
//log or do whatever.
};
$sql = "SELECT Field1 as FieldA, field2 as FieldB, ... from Table where ID='something'";
$results = array();
if($result = mysqli_query($con, $sql))
{
while($row = mysqli_fetch_assoc($result))
{
$results[] = $row;
}
}
else
{
//log if it failed for some reason
die();
}
$obj->Data = $results;
$obj->Error = '';
die(json_encode($obj));
Question is: how can I overcome the issue regarding the size of the array / illegal characters (if that's the case)?
Your "Version 1" seems to be correct from a PHP perspective, but you need to actually handle the errors - both when connecting and when performing the query. Doing so would have told you that you don't actually query a table, you're missing FROM tablename in the query.
Use mysqli_connect_error() when connecting, and mysqli_error($con) when querying to get back the actual errors. General PHP error-reporting might also help you.
The code below assumes that $parameter is defined prior to this code.
$con = mysqli_connect('host','account','password','database_name');
if (mysqli_connect_errno())
die("An error occurred while connecting: ".mysqli_connect_error());
$sql = "SELECT field1 as Field1, field2 as Field2
FROM table
WHERE ID = '".$parameter."'";
$results = array();
if ($result = mysqli_query($con, $sql)) {
while ($row = mysqli_fetch_assoc($result)) {
$results[] = $row;
}
return $results;
} else {
return mysqli_error($con);
}
Error-reporing
Adding
error_reporting(E_ALL);
ini_set("display_errors", 1);
at the top of your file, directly after <?php would enable you to get the PHP errors.
NOTE: Errors should never be displayed in a live environment, as it might be exploited by others. While developing, it's handy and eases troubleshooting - but it should never be displayed otherwise.
Security
You should also note that this code is vulnerable to SQL-injection, and that you should use parameterized queries with placeholders to protect yourself against that. Your code would look like this with using prepared statements:
$con = mysqli_connect('host','account','password','database_name');
if (mysqli_connect_errno())
die("An error occurred while connecting: ".mysqli_connect_error())
$results = array();
if ($stmt = mysqli_prepare("SELECT field1 as Field1, field2 as Field2
FROM table
WHERE ID = ?")) {
if (mysqli_stmt_bind_param($stmt, "s", $parameter)) {
/* "s" indicates that the first placeholder and $parameter is a string */
/* If it's an integer, use "i" instead */
if (mysqli_stmt_execute($stmt)) {
if (mysqli_stmt_bind_result($stmt, $field1, $field2) {
while (mysqli_stmt_fetch($stmt)) {
/* Use $field1 and $field2 here */
}
/* Done getting the data, you can now return */
return true;
} else {
error_log("bind_result failed: ".mysqli_stmt_error($stmt));
return false;
}
} else {
error_log("execute failed: ".mysqli_stmt_error($stmt));
return false;
}
} else {
error_log("bind_param failed: ".mysqli_stmt_error($stmt));
return false;
}
} else {
error_log("prepare failed: ".mysqli_stmt_error($stmt));
return false;
}
References
http://php.net/mysqli.prepare
How can I prevent SQL injection in PHP?

Using PHP to query a MDB file, and return JSON

I have a Microsoft Access Database, and I am trying to query the table using PHP, and output valid JSON. I have an equivalent code for a MSSQL database, am I am trying to make my code do the same thing, but just for the Access database.
Here is the MSSQL code
$myServer = "server";
$myDB = "db";
$conn = sqlsrv_connect ($myServer, array('Database'=>$myDB));
$sql = "SELECT *
FROM db.dbo.table";
$data = sqlsrv_query ($conn, $sql);
$result = array();
do {
while ($row = sqlsrv_fetch_array ($data, SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
} while (sqlsrv_next_result($data));
$json = json_encode ($result);
sqlsrv_free_stmt ($data);
sqlsrv_close ($conn);
Here is what I tried for the MDB file
$dbName = "/filename.mdb";
if (!file_exists($dbName)) {
die("Could not find database file.");
}
$db = odbc_connect("Driver={Microsoft Access Driver (*.mdb)};Dbq=$dbName", $user, $password);
$sql = "SELECT *
FROM cemetery";
$data = $db->query($sql); // I'm getting an error here
$result = array();
// Not sure what do do for this part...
do {
while ($row = fetch($data, SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
} while (sqlsrv_next_result($data));
$json = json_encode ($result);
I kind of followed this to try to connect to the database: http://phpmaster.com/using-an-access-database-with-php/
Currently this is giving me a 500 Internal Server Error. I'm expecting a string such as this to be saved in the variable $json
[
{
"col1":"col value",
"col2":"col value",
"col3":"col value",
},
{
"col1":"col value",
"col2":"col value",
"col3":"col value",
},
{
etc...
}
]
Can someone help me port the MSSQL code I have above so I can use it with an MDB database? Thanks for the help!
EDIT: I'm commenting out the lines one by one, and it throws me the 500 error at the line $data = $db->query($sql);. I looked in the error log, and I'm getting the error Call to a member function query() on a non-object. I already have the line extension=php_pdo_odbc.dll uncommented in my php.ini file. Anyone know what the problem could be?
You only need 1 loop,
fetchAll is your iterable friend:
while ($row = $data->fetchAll(SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
odbc_connect doesn't return an object, it returns a resource. see (http://php.net/manual/en/function.odbc-connect.php) so you would need to do something like this.
$db = odbc_connect("Driver={Microsoft Access Driver (*.mdb)};Dbq=$dbName", $user, $password);
$oexec = obdc_exec($db,$sql);
$result[] = odbc_fetch_array($oexec);
and then you can iterate over results..
see also:
http://www.php.net/manual/en/function.odbc-fetch-array.php
http://www.php.net/manual/en/function.odbc-exec.php
I finally figured it out.
<?php
// Location of database. For some reason I could only get it to work in
// the same location as the site. It's probably an easy fix though
$dbName = "dbName.mdb";
$tName = "table";
// Throws an error if the database cannot be found
if (!file_exists($dbName)) {
die("Could not find database file.");
}
// Connects to the database
// Assumes there is no username or password
$conn = odbc_connect("Driver={Microsoft Access Driver (*.mdb)};Dbq=$dbName", '', '');
// This is the query
// You have to have each column you select in the format tableName.[ColumnName]
$sql = "SELECT $tName.[ColumnOne], $tName.[ColumnTwo], etc...
FROM $dbName.$tName";
// Runs the query above in the table
$rs = odbc_exec($conn, $sql);
// This message is displayed if the query has an error in it
if (!$rs) {
exit("There is an error in the SQL!");
}
$data = array();
$i = 0;
// Grabs all the rows, saves it in $data
while( $row = odbc_fetch_array($rs) ) {
$data[$i] = $row;
$i++;
}
odbc_close($conn); // Closes the connection
$json = json_encode($data); // Generates the JSON, saves it in a variable
?>
I use this code to get results from an ODBC query into a JSON array:
$response = null;
$conn = null;
try {
$odbc_name = 'myODBC'; //<-ODBC connectyion name as is in the Windows "Data Sources (ODBC) administrator"
$sql_query = "SELECT * FROM table;";
$conn = odbc_connect($odbc_name, 'user', 'pass');
$result = odbc_exec($conn, $sql_query);
//this will show all results:
//echo odbc_result_all($result);
//this will fetch row by row and allows to change column name, format, etc:
while( $row = odbc_fetch_array($result) ) {
$json['cod_sistema'] = $row['cod_sistema'];
$json['sistema'] = $row['sistema'];
$json['cod_subsistema'] = $row['cod_subsistema'];
$json['sub_sistema'] = $row['sub_sistema'];
$json['cod_funcion'] = $row['cod_funcion'];
$json['funcion'] = $row['funcion'];
$json['func_desc_abrev'] = $row['desc_abreviada'];
$json['cod_tipo_funcion'] = $row['cod_tipo_funcion'];
$response[] = array('funcionalidad' => $json);
}
odbc_free_result($result); //<- Release used resources
} catch (Exception $e) {
$response = array('resultado' => 'err', 'detalle' => $e->getMessage());
echo 'ERROR: ', $e->getMessage(), "\n";
}
odbc_close($conn);
return $response;
And finnally encoding the response in JSON format:
echo json_encode($response);

I can't get result from mysqli query with PHP (converted from mysql_result)

I have a PHP function that I am converting from using the mysql extension to the mysqli extension.
Everything is going okay, until here. I previously used a mysql_result to get a single piece of data. There is no direct equivalent in mysqli, so I have tried the following but it still doesn't work.
function getdbvalue($table,$value,$idfield,$id) {
$qrytext = "SELECT $value FROM $table WHERE $idfield LIKE '$id'";
$valueqry = mysqli_query($dbh,$qrytext);
if (FALSE === $valueqry) die("Select failed: ".mysqli_error);
$result = mysqli_fetch_row($valueqry);
$returnvalue = $result[0];
return $returnvalue;
}
I have verified that the variables are passing to the function okay, and the function is actually getting triggered. If I return $id I see the ID numbers.
I don't get an error for the query.
SOLVED:
I needed to add the database connection variable as a global in the function:
Working code:
function getdbvalue($table,$value,$idfield,$id) {
global $dbh; // This was missing!
$qrytext = "SELECT $value FROM $table WHERE $idfield LIKE '$id'";
$valueqry = mysqli_query($dbh,$qrytext);
if (FALSE === $valueqry) die("Select failed: ".mysqli_error);
$result = mysqli_fetch_row($valueqry);
$returnvalue = $result[0];
return $returnvalue;
}
Thanks to everyone for their help. :)
Although it's good idea to automate simple selects, the implementation is highly insecure, and should never be used.
Make it accept SQL query and parameters. It will make it secure.
And also you have to use PDO instead of mysqli
function getdbvalue() {
global $pdo;
$args = func_get_args();
$sql = array_shift($args);
$stm = $pdo->prepare($sql);
$stm->execute($args);
return $stm->fetchColumn();
}
have to be used like this (you have to connect to PDO first):
$name = getdbvalue("SELECT name FROM users WHERE id=?", $is);
this is the only proper way

Help with mysqli and multiple queries

I've never had to use mysqli until today and cannot seem to get this right. What I want is a simple function that will accept a mysql procedure call and have it return those results.
When I started using these procedures, I noticed that the old way of querying the database, using mysql_query, would no longer get me the expected results; one procedure would successfully return and the other would not. After reading the manual and several other examples out there, I found that the reason for this odd behavior was because the results need to be buffered then cleared. I have tried several ways of doing this and have been unsuccessful.
What I have so far works if I create another instance of the mysqli object and will get me both results however, I don't think it's right that I should have to instantiate 20 different objects to get back 20 different queries.
Again, what I want here, is to have a single function that I can feed a procedure to and have the results returned back.
$mysqli = new mysqli('host','user','password','test');
$rs = $mysqli->query('CALL titles()');
while($row = $rs->fetch_object())
{
print_r($row);
}
$mysqli2 = new mysqli('host','user','password','test');
$rs2 = $mysqli2->query('CALL colours()');
while($row2 = $rs2->fetch_object())
{
print_r($row2);
}
you can make a class for this:
db.php // A db class. Call this you perform a query.
<?php
class MyConnection{
var $db_host = 'Localhost';
var $db_user = 'mYUserName';
var $db_password = 'myPassword';
var $db_name = 'mYDB';
var $connection;
function Connect(){
$this->connection = #mysqli_connect($this->db_host, $this->db_user, $this->db_password)
or
die("Error: ".mysqli_connect_error());
mysqli_select_db($this->connection, $this->db_name);
mysqli_query($this->connection, "SET NAMES 'utf8'");
}
function Disconnect(){
mysqli_close($this->connection);
}
function ExecSQL($query){
$result = mysqli_query($this->connection, $query)
or
die('Error: '.mysqli_error($this->connection));
return $result;
}
}
?>
Implementation:
include "db.php";
$conn = new MyConnection;
$conn->Connect();
$rs = $conn->ExecSQL('CALL titles()');
while($row = $rs->fetch_object())
{
print_r($row);
}
$rs2 = $conn->ExecSQL('CALL colours()');
while($row2 = $rs2->fetch_object())
{
print_r($row2);
}
$conn->Disconnect();

Categories