UPDATE VARBINARY(MAX) column in SQL Server table with $_FILE image upload - php

I've been looking all across the internet for help on this and have found nothing.
Basically I need to know how to update a SQL Server VARBINARY(MAX) column with the hex of an image uploaded from a HTML form. The database is in a different place to the HTML form, so move_uploaded_file in PHP then OPENROWSET (BULK ...) in SQL doesn't work (unable to find the file).
I also tried doing file_get_contents on the uploaded $_FILE['name_']['tmp_name'], then used unpack("H*hex") and put the result of that into the SQL column with a "0x" prepend, but that crashes, saying it needs to be converted from a VARCHAR to a VARBINARY. When I convert it, the code runs and the column is populated, but the image is malformed.
No idea what to do next. Pls help.

Solution:
This is a basic approach using PHP Driver for SQL Server:
Table creation (T-SQL):
CREATE TABLE [dbo].[ImageTable] (
[ImageData] varbinary(max) NULL
)
PHP:
<?php
# Connection
$server = 'server\instance,port';
$database = 'database';
$uid = 'user';
$pwd = 'password';
$cinfo = array(
"Database" => $database,
"UID" => $uid,
"PWD" => $pwd
);
$conn = sqlsrv_connect($server, $cinfo);
if( $conn === false )
{
echo "Error (sqlsrv_connect): ".print_r(sqlsrv_errors(), true);
exit;
}
# Update image using CONVERT()
$image = file_get_contents('image.jpg');
$sql = "UPDATE ImageTable SET [ImageData] = CONVERT(varbinary(max), ?) WHERE (yor_update_condition)";
$params = array(
array($image, SQLSRV_PARAM_IN)
);
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
echo "Error (sqlsrv_query): ".print_r(sqlsrv_errors(), true);
exit;
}
# End
echo 'Image updated.'
?>

Related

php - how execute a sqlsrv stored procedure

I have a successful connection to SQL Server using SQLSRV in my PHP script:
$name = 'SERVERNAME';
$db = 'DBNAME';
$par = array("Database"=>$db);
$conn = sqlsrv_connect($name, $par);
Also I have the following T-SQL script:
Declare #dt datetime;
SET #dt = GETDATE();
EXEC oik..SrezLTGES #Cat = 'Ë', #Ids = '140539,140540,140589,150395,180395,180396,180445',#Time = #dt
The procedure parameters are:
I don't know how to execute this query in PHP. Any ideas?
A possible approach here is to parameterize the statement and use sqlsrv_query(). As is mentioned in the documentation, the sqlsrv_query function is well-suited for one-time queries and should be the default choice to execute queries unless special circumstances apply and sqlsrv_query function does both statement preparation and statement execution, and can be used to execute parameterized queries.
The stored procedure has varchar parameters (and I'm almost sure, that you are using a cyrillic collation), so you may need to use the appropriate encoding ("CharacterSet" => "UTF-8" or "CharacterSet" => SQLSRV_ENC_CHAR in the connection options) and/or character set conversion on the parameters values (with iconv() for example). Reading UTF-8 all the way through is a good starting point.
If the stored procedure returns data, you may try to use sqlsrv_fetch_array() to retrieve the returned data. You may also use SET NOCOUNT ON to prevent SQL Server from passing the count of the affected rows as part of the result set.
The following example, based on your code, is a possible solution to your problem:
<?php
// Connection
$server = "SERVERNAME";
$database = "DBNAME";
$cinfo = array(
"CharacterSet" => "UTF-8",
"Database" => $database
);
$con = sqlsrv_connect($server, $cinfo);
if ($con === false) {
echo "Error (sqlsrv_connect): ".print_r(sqlsrv_errors(), true);
exit;
}
// Statement
$sql = "
SET NOCOUNT ON;
DECLARE #dt datetime;
SET #dt = GETDATE();
EXEC oik..SrezLTGES
#Cat = ?,
#Ids = ?,
#Time = #dt,
#TimeIsSummer = 1,
#ShowSystemTime = 1
";
$params = array("Ë", "140539,140540,140589,150395,180395,180396,180445");
$stmt = sqlsrv_query($con, $sql, $params);
if ($stmt === false) {
echo "Error (sqlsrv_query): ".print_r(sqlsrv_errors(), true);
exit;
}
// Data
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
echo print_r($row, true);
}
// End
sqlsrv_free_stmt($stmt);
sqlsrv_close($con);
?>

Length of output parameter in sqlsrv - 01004 (Data truncated)

I have stored procedures in SQL Server that output data as xml datatype. When I try to get the output parameter in PHP with PHP Driver for SQL Server (sqlsrv extension) and the string is longer than 4000 I get an SQL Error (SQLSTATE 01004 (Data truncated)).
Here is a short example:
Stored Procedure:
CREATE PROCEDURE pr_getlargexml
#xml xml OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET #xml =
(
SELECT *
FROM largeTable
FOR XML RAW, ELEMENTS, TYPE, ROOT('xml')
);
END;
GO
PHP code:
$serverName = "localhost\SQL2012TEST";
$connectionInfo = array("Database" => "TEST", "UID" => "", "PWD" => "");
$conn = sqlsrv_connect($serverName, $connectionInfo);
if ($conn === false) {
die(print_r(sqlsrv_errors(), true));
}
$retval = '';
$query = sqlsrv_query($conn, 'EXEC pr_getlargexml ?',array(array(&$retval,SQLSRV_PARAM_OUT,SQLSRV_PHPTYPE_STRING('UTF-8'),SQLSRV_SQLTYPE_XML)));
if ($query === false) {
die(print_r(sqlsrv_errors(), true));
}
echo "<pre>";
\var_dump($retval);
echo "</pre>";
If the xml is shorter than 4000, it works fine. I also tried to use nvarchar(max) as datatype in sql and SQLSRV_SQLTYPE_NVARCHAR('max') in php as sqltype, but I get the same Error.
Has anyone a solution for my problem?

PHP PDO MySQL: Insert statement runs without error, no insert occurs

My code:
<?php
try {
$t = '040485c4-2eba-11e9-8e3c-0231844357e8';
if (array_key_exists('t', $_REQUEST)) {
$t = $_REQUEST["t"];
}
if (!isset($_COOKIE['writer'])) {
header("Location: xxx");
return 0;
}
$writer = $_COOKIE['writer'];
$dbhost = $_SERVER['RDS_HOSTNAME'];
$dbport = $_SERVER['RDS_PORT'];
$dbname = $_SERVER['RDS_DB_NAME'];
$charset = 'utf8' ;
$dsn = "mysql:host={$dbhost};port={$dbport};dbname={$dbname};charset={$charset}";
$username = $_SERVER['RDS_USERNAME'];
$password = $_SERVER['RDS_PASSWORD'];
$pdo = new PDO($dsn, $username, $password);
$stmt = $pdo->prepare("select writer from mydbtbl where writer=? and t=?");
$stmt->execute(array($writer, $t));
$num = $stmt->fetch(PDO::FETCH_NUM);
if ($num < 1) {
header("Location: login.php");
return 0;
}
$dbMsg = "Authorized";
$dbname = 'imgs';
$dsn = "mysql:host={$dbhost};port={$dbport};dbname={$dbname};charset={$charset}";
$pdo = new PDO($dsn, $username, $password);
if (isset($_FILES['filename'])) {
$name = $_FILES['filename']['name'];
// set path of uploaded file
$path = "./".basename($_FILES['filename']['name']);
// move file to current directory
move_uploaded_file($_FILES['filename']['tmp_name'], $path);
// get file contents
$data = file_get_contents($path, NULL, NULL, 0, 60000);
$stmt = $pdo->prepare("INSERT INTO file (contents, filename, t) values (?,?,?)");
$stmt->execute(array
($data,
$name,
$t)
);
$dbMsg = "Added the file to the repository";
// delete the file
unlink($path);
}
} catch (Exception $e) {
$dbMsg = "exception: " . $e->getMessage();
}
In the code you will see that the first part is for doing authentication. Then I create a new PDO object on the img schema, and do my file insert query after that.
Later, where I am printing out $dbMsg, it is saying "added file to the repository". But when I query the database (MySQL on Amazon AWS using MySQL Workbench) nothing has been inserted.
I don't understand why if nothing is getting inserted I am not getting an error message. If it says "added file to the respository", doesn't that mean the insert was successful? The only thing I can think is that using a different schema for this is mucking things up. All of my inserts to ebdb are going through fine
--- EDIT ---
This question was marked as a possible duplicate on my query about not getting an error message on my insert / execute code. This was a useful link and definitely something I will be aware of and check in the future, but ultimately the answer is the one I have provided regarding the terms of service for my aws account
The answer is that the (free) amazon account policy I am working under only allows me to have 1 database / schema. When I switched the table over to ebdb it worked right away. I am answering my own question (rather than deleting) so hopefully others using AWS / MySQL can learn from my experience.

Store Image path in MYSQL with PHP

My PHP file need to save the image in a server and store the image path in a MYSQL database.
My database imageid contains table image_table as below :
create table image_table
(
ID INT not null AUTO_INCREMENT,
path varchar(256),
primary key (ID)
)
My PHP Code is as below. Image saving in the server is working fine, but throws few errors storing the image path in DB.
Error running the below PHP code :
Parse error: syntax error, unexpected '$conn' (T_VARIABLE) in C:\xampp\htdocs\appinventor\postfile.php on line 7
The PHP Code with above error:
<?PHP
$servername = "localhost";
$username = "root";
$password = "basis123";
$database = "imageid"
// Create connection
$conn = new mysqli($servername, $username, $password);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully";
#mysqli_select_db($database) or die( "Unable to select database");
$query = "INSERT INTO image_table (path) VALUES('$_GET['filename']')");
//mysql_query($query);
//File Transfer Logic
$data = file_get_contents('php://input');
if (!(file_put_contents($_GET['filename'],$data) === FALSE)) echo "File xfer completed."; // file could be empty, though
else echo "File xfer failed.";
// $_GET['filename'] has the file name . and C:\xampp\htdocs\myapp is the file path
echo $_GET['filename']
//mysql_close();
?>
When i remove the database connection and SQLQuery in php code the connection is successful.
Removed lines of code for successful connection and log as "Connected successful"
#mysqli_select_db($database) or die( "Unable to select database");
$query = "INSERT INTO image_table (path) VALUES('$_GET['filename']')");
//mysql_query($query);
Where did i go wrong ?Any suggestions ?
You forgot semicolon after $database = "imageid"
$database = "imageid";
And you have extraneous parenthesis here:
$query = "INSERT INTO image_table (path) VALUES('$_GET['filename']')");
Try this:
<?php
$servername = "localhost";
$username = "root";
$password = "basis123";
$database = "imageid";
// Create connection
$conn = new mysqli($servername, $username, $password,$database);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully";
mysqli_select_db($conn,$database);
$query = "INSERT INTO image_table (path) VALUES('".$_GET['filename']."')";//also this is unsafe
//mysql_query($query);
//File Transfer Logic
$data = file_get_contents('php://input');
if (!(file_put_contents($_GET['filename'],$data) === FALSE)) echo "File xfer completed."; // file could be empty, though
else echo "File xfer failed.";
// $_GET['filename'] has the file name . and C:\xampp\htdocs\myapp is the file path
echo $_GET['filename']
//mysql_close();
?>
Main problem:
$database = "imageid"
^----missing ;
$conn = new m
PHP strings+arrays 101: You cannot use quoted array keys within a double-quoted string, unless you use the {}-extended syntax:
$foo = "$arr['key']"; // bad
$foo = "$arr[key]"; // ok
$foo = "{$arr['key']}"; // ok
So:
$query = "INSERT INTO image_table (path) VALUES('$_GET['filename']')");
^--------^
is wrong, as well as being vulnerable to SQL injection attacks.
You need a semi colon after
$database = "imageid"
so it should be
$database = "imageid";
You also don't want to be putting user input directly into your SQL. http://en.wikipedia.org/wiki/SQL_injection

PHP connect to SQL server on different machines

I have a PHP website on a Windows machine and would like to insert data DIRECTLY to SQL database which is located on IIS server on a different machine?
Which approach shall I follow?
**My initial thought was to divert to a PHP page hosted by IIS that executes a query and then redirect back to my website. However, I prefer something easier and less complicated approach.
IIS is on Windows Server 2008 R2.
Your help is appreciated very much. Thanks!
If you're using PHP, you can open a connection to a database on another machine using PDO:
$remotedb = new PDO("*dbtype*:dbname=*dbname*;host=*addressOfOtherMachine*", $user, $password);
http://www.php.net/manual/en/class.pdo.php
I use SQLSRV in PHP to connect to a database on an IIS6 machine with 2008 R2. I believe the remote machine must allow remote connections and needs to be turned on through the settings if it isn't. Here is what my connection string looks like:
<?php
/* NEW CONNECTION FOR SQLSRV DRIVER (for MSSQL access) */
$uid = "username";
$pwd = "password";
$DB = "database_name";
$serverName = "ip_address_of_remote_server (example: 192.168.0.25)";
$connectionInfo = array("UID" => $uid, "PWD" => $pwd, "Database"=> $DB, "ReturnDatesAsStrings" => true);
$conn = sqlsrv_connect( $serverName, $connectionInfo);
?>
Here is a sample parameterized insert query using the connection:
<?php
$p1 = "values passed from a form";
$p2 = "values passed from a form";
$p3 = "values passed from a form";
$params = array(
array(&$p1, null, null, SQLSRV_SQLTYPE_VARCHAR(50)),
array(&$p2, null, null, SQLSRV_SQLTYPE_DATETIME),
array(&$p3, null, null, SQLSRV_SQLTYPE_VARCHAR(50))
);
$sql = "INSERT INTO database_name (column1, column2, column3) values (?,?,?)";
$stmt = sqlsrv_prepare($conn, $sql, $params);
if( !$stmt ) { die( print_r( sqlsrv_errors(), true)); }
if(sqlsrv_execute( $stmt ) === false ) { die( print_r( sqlsrv_errors(), true)); }
?>
For more SQLSRV params, visit http://msdn.microsoft.com/en-us/library/cc626305.aspx

Categories