Convert number value from php to varbinary in mysql - php

In MYSQL database, I have a varbinary(255) field.
In my PHP script, I am trying to pass the input of string (either in decimal or hex) to MYSQL to save the value in varbinary(255). I tried passing the value in decimal, hexadecimal, and binary, but none of them gave me the correct value.
$val = "0x54321"; // Used hardcoded hex value here, but it can be also decimal in my code
$v_dec = intval($val,0); // That's why I have intval() here
$v_hex = dechex(intval($val,0));
$v_bin = decbin(intval($val,0));
$v_bin_2 = (binary)intval($val,0);
I tried inserting these values using regular INSERT query, but each of them gave weird numbers.
Variable Converted Value (in php) varbinary Value (in MYSQL)
v_dec: 344865 -> 333434383635
v_hex: 54321 -> 3534333231
v_bin: 1010100001100100001 -> 31303130313030303031313030313030303031
v_bin2: 344865 -> 333434383635
What data type should the value be in? I want to do the conversion in php instead of using CAST() in the MYSQL query. Thanks!
EDIT:
What I want to do is to correctly display the saved varbinary value in hex.
EDIT:
Found the problem. The problem was how I was retrieving the value. Instead of HEX(value), I retrieved it as BIN(value) in mysql level and then converted it into hex with dechex(bindec($value)) in php.

Related

Not receiving correct data from firebird database when using PHP

I have some very odd situation. I am making a query to a firebird database and there is mismatch with the result in PHP. In DB the result is just fine, but when it comes to PHP there are different values.
The query:
SELECT LIST(t."ID", ',') ID,t."Date", LIST(n."Name",',') Name
FROM "Tests" t
LEFT JOIN "Names of tests" n ON t."Name ID" = n."ID"
WHERE t."Locked" = 0
GROUP BY t."Date"
ORDER BY t."Date" DESC
Result in DB:
ID = 546,552 Date = 23.10.2015 Name = Математика (тест),География(тест)
Result in PHP:
ID => 0x0000000200000000,
Date => 2015-10-23,
Name => 0x0000000500000000
I am using "UTF-8" encoding when connecting to DB with ibase_connect() the database encoding is WIN1251.
The result type of LIST() is a blob, not a CHAR or VARCHAR. I don't use PHP myself, but I believe that the Firebird/Interbase driver for PHP requires you to explicitly request the blob.
The values you see for ID and Name are the blob ids that can be used to request the blobs.
You have two options:
Request the blob value using these blob ids, see ibase_blob_open and ibase_blob_get (afaik, you will need to do the correct byte to character conversion yourself)
Cast the value to a VARCHAR (eg CAST(LIST(t."ID", ',') AS VARCHAR(2048)) AS ID)
The downside of the second option is that if you can have really long results, then you also need to cast to a long VARCHAR, otherwise you get truncation errors; and unfortunately varchars are restricted to 32K-2 bytes (8191 characters for UTF8), and a row as a whole to 64K bytes.

how to get the full data from nvarchar?

fetching a data from sql server 2000
type nvarchar with length 1500
when i try to print it using print_r or echo in php
the message gets cut off to 255 char, there is no error, and
in database the message is there, but i cant fetch them all
how do i fix this ?
example field message
i just use simple fetch function it work, just cant get the full data
$result = "some query here"
while($line = $VinDB->fetch_array($result)){
if (#$line["message"] != null)
{echo #$line["message"];}
}
If you are using the mssql extension, you have to consider either to change the original type of the column to TEXT/NTEXT, or to cast it to TEXT/NTEXT.
There is a bug in the old extension:
Note: Note to Windows Users:
Due to a limitation in the underlying API used by PHP (MS DBLib C API), the length of VARCHAR fields is limited to 255. If you need to store more data, use a TEXT field instead.
From: http://www.php.net/manual/en/function.mssql-field-length.php
I think you should try setting the data type to text or ntext. It might be an issue regarding the max character limit on nvarchar.

XOR encode a multibyte string and save to MySQL field without loss

I'm currently using this function to obfuscate a bit the field values in MySQL and protect it from direct dumping. It all works good and values are stored correctly, but what happens when i try to store a multibyte string?
Here's an example, let's try to encode the string álex:
<?
$v = xorencode('álex');
// step 1 - encode
echo $v."\n";
// step 2 - decode
echo xorencode($v);
?>
Works good, i see some obfuscated string first time, and then i see álex again. Now if i try to save it in a VARCHAR field in a MySQL table, and then select it - i no longer have a utf string, instead it gets returned as gllex.
Note, MySQL tables and fields collations are utf8_general_ci, files are UTF-8, and i SET NAMES utf8 after connecting. Any workaround to this?
Thanks

Conversion of MySQL binary GEOMETRY fields in PHP

I’m working on an application integrating mapquest maps and using the mapquest API.
At this moment I want to achieve the following: the registered user has to input latitude and longitude information, and in the database this information has to be stored as geometry type field. Conversely, a user looking at their account should see the latitude and longitude information that was entered.
In an earlier simplified codebase I achieved this directly in the MySQL query, by using the MySQL functions AsText and GeomFromText. But now I’m on CodeIgniter and need to do the conversion in PHP
Is there anything equivalent in PHP to MySQL's AsText and GeomFromText functions?
It appears that the PHP unpack function is what is needed to extract the coordinate information.
MySQL stores the geometry fields in the WKB (Well Known Binary) format. The unpack function is able to extract that information when provided the proper format specifier. The following code is from a test script which successfully extracted the desired information.
Please note that my format for unpack differs slightly from that of the reference. This is because the WKB string wasn't retrieved from MySQL with the AsWKB() function, so it contains extra padding.
<?php
$padding = 0;
$order = 1;
$gtype = 1;
$lon = -73.91353;
$lat = 42.80611;
$bindata = pack('LcLd2', $padding, $order, $gtype, $lat, $lon);
printf("Packed: %s\n\n", bin2hex($bindata));
$result = unpack('Lpadding/corder/Lgtype/dlatitude/dlongitude', $bindata);
var_dump($result);
?>
References MySQL and ESRI Network.
I, too, am trying to extract geometry field data.I am using the MySQLi class to retrieve rows of data and display it according to field type.
While I haven't yet figured out how to decode the geometry field data, I can view it by using the bin2hex function. A point stored using GeomFromText('POINT(-73.91353 42.80611)')
using bin2hex gives me a 50 character string value of
0000000001010000008d7a8846777a52c0417dcb9c2e674540
A partial list of field type numbers can be found here.
I hope that this helps you! If I discover more, I'll pass it on here.

MD5 Hashes not matching

I am trying to match a md5 has (generated through php) to its original value in a SQLExpress database.
I am using the following function in my SQL query
master.sys.fn_varbintohexsubstring(0, HASHBYTES('MD5', 'ID'), 1, 0)
Where 'ID' is the field in the database.
However they both seem to return different values for the md5 hash. I have been using '12290' as a static value to test this.
php md5() returns: 0bd81786a8ec6ae9b22cbb3cb4d88179
The following SQL Statement returns the same output:
DECLARE #password VARCHAR(255)
SET #password = master.sys.fn_varbintohexsubstring(0, HASHBYTES('MD5', '12290'), 1, 0)
SELECT #password
Yet when I run the following statement from the table:
SELECT ID, master.sys.fn_varbintohexsubstring(0, HASHBYTES('MD5', CONVERT(NVARCHAR(255), ID)), 1, 0) AS temp
FROM Clients
ORDER BY ID ASC
The 'temp' value matching to the 'ID' value of 12290 returns: 1867dce5f1ee1ddb46ff0ccd1fc58e03
Any help on the matter would be much appreciated!
Thanks
Python helped me to help you.
>>> from hashlib import md5
>>> md5('1\x002\x002\x009\x000\x00').digest().encode('hex')
'1867dce5f1ee1ddb46ff0ccd1fc58e03'
NVARCHAR is Unicode type and it seems from the above experiment that '12990' is stored as UTF-16LE in your database: '1\02\09\09\00\0'.
Assuming that the data encoding in the PHP is UTF-8 data and you don't want to change the existing data in the database, this is how you can fix your PHP script:
<?php
$password = '12290';
$hash = md5(mb_convert_encoding($password, 'UTF-16LE', 'UTF-8')) . "\n";
echo $hash;
?>
Output:
susam#swift:~$ php utf16le-hash.php
1867dce5f1ee1ddb46ff0ccd1fc58e03
In case the data in PHP is in some other encoding such as ASCII, ISO-8859-1, etc. you can change the third argument to mb_convert_encoding accordingly. The list of all supported encodings is available at: http://www.php.net/manual/en/mbstring.supported-encodings.php
Also, see http://www.php.net/manual/en/function.mb-convert-encoding.php
I don't have SQL server to test this on, but the CONVERT command might be creating the NVARCHAR with 240-odd trailing blanks (as you have specified NVARCHAR(255))
Try setting the NVARCHAR to the length of the ID to test:
ARE #password VARCHAR(255)
SET #password = master.sys.fn_varbintohexsubstring(0, HASHBYTES('MD5', CONVERT(NVARCHAR(5), '12290')), 1, 0)
SELECT #password
Try with different lengths in the CONVERT - is there any difference?
One of two things is most likely the problem:
Either the ID column in that row has a value not exactly equal to '12290' (e.g. extra whitespace)
Or the CONVERT function produces such a value
In any case, a standard debugging approach would be to use an SQL query to SELECT the string lengths of that ID field and the return value of CONVERT; if either is not equal to 5, you found the error.
Alternatively you can perform a dump of the table in question including data, and look at the generated INSERT statement to see what the database says the value in that column is.

Categories