This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
Hey guys I have the following:
session_start();
$seterror = 0;
function returnBack(){
header("Location:../memberinterface.php?getmsg=15");
exit;
}
function returnBackfile(){
header("Location:../memberinterface.php?getmsg=16");
exit;
}
if (!empty($_FILES['csvfile']['error'] ) )
{
$seterror = 1;
returnBack();
}
if (empty($_POST['firstname'])){
$seterror =1;
returnBack();
}
if (empty($_POST['lastname'])){
$seterrro =1;
returnBack();
}
if (empty($_POST['email'])){
$seterror =1;
returnBack();
}
if ($seterror !== 1){
$file = $_FILES['csvfile']['tmp_name'];
$handle = fopen($file , "r");
$fileop = fgetcsv($handle,0,"\t");
echo '<pre>'; var_dump($fileop); var_dump($_POST); echo '</pre>';
exit;
$fileop=array_map("strtoupper",array_map("trim",$fileop));
$firstname_index = array_search(strtoupper($_POST["firstname"]),$fileop);
if ($firstname_index===false){
returnBack();
}
$lastname_index = array_search(strtoupper($_POST["lastname"]),$fileop);
if ($lastname_index===false){
returnBack();
}
$email_index = array_search(strtoupper($_POST["email"]),$fileop);
if ($email_index===false){
returnBack();
}
//open file and store values
$j = 0;
while (($fileop=fgetcsv($handle,0,"\t")) !== false)
{
$fileop=array_map("trim",$fileop);
$firstname[$j] = $fileop[$firstname_index];
if (empty($firstname[$j])){
returnBackfile();
}
$lastname[$j] = $fileop[$lastname_index];
if (empty($lastname[$j])){
returnBackfile();
}
$email[$j] = $fileop[$email_index];
if (empty($email[$j])){
returnBackfile();
}
$j++;
}
//create sessions, send back to memberinterface.php and open table to display the results to delete
$_SESSION['CSVRfirstnames'] = $firstname;
$_SESSION['CSVRlastnames'] = $lastname;
$_SESSION['CSVRemails'] = $email;
header("Location:../memberinterface.php?RemoveCSV=1");
}
And the section where I echo out the columns: echo '<pre>'; var_dump($fileop); var_dump($_POST); echo '</pre>'; - a weird thing happens.
For some CSV files I get this outprinted:
array(4) {
[0]=>
string(726) "PK!|l˜l [Content_Types].xml ¢( Ì”]KÃ0†ïÿCÉ4Ù&ˆÈº]øq©çˆÍé–&!'›Û¿÷4û#¤nzÓÐæœ÷}’4ïp¼jL¶„€ÚÙ‚õye`K§´ìmú”ß²£´Jg¡`k#6]^§k˜Q·Å‚Õ1ú;!°¬¡‘ÈK3•ŒôfÂËr.g ½Þ(`c[
6>#%&f+ú¼!"
[1]=>
string(71) "`e÷›ÂÖ«`Ò{£K‰T,úæ’o8u¦¬µÇ+Â`¢Ó¡ùÙ`Û÷B[´‚l"C|–
aˆ•.Ìß›óÃ"”®ªt"
[2]=>
string(951) "v€£ Ö±1<¼‘Úî¸ø§bi蟤]_>‘cðO8®ÿˆ#Òÿ"=$IæÈ`\À3¯v#z̹–Ôk”gøª}ˆƒîÑ$8”(Nß…]d´Ý¹'!QÃ>4º.ßÞ‘ÒètÃo·Ú¼S :¼EÊ×Ñ'ÿÿPK!µU0#õL_rels/.rels ¢( Œ’ÏNÃ0ÆïH¼CäûênH¡¥»LH»!TÀ$îµ£$#÷ö„‚JcÛÑöçÏ?[ÞîæiTb/Nú(A±3b{×jxŸV b"giÇŽaWÝÞl_x¤”›b×û¨²‹‹º”ü#b4Oñìr¥‘0QÊahÑ“¨eÜ”å=†¿P-<ÕÁj{ª>ú<ù²·4Mox/æ}b—NŒ#ž;ËvåCf©ÏÛ¨šBËIƒóœÓÉû"cž&Ú\Oôÿ¶8q"K‰ÐHàó<ߊs#ëë.Ÿh©ø½Î<⧄áMdøaÁÅT_ÿÿPK!Þ"
[3]=>
string(530) "(Ôxl/_rels/workbook.xml.rels ¢( ¼“ÏjÃ0ÆƒÑ}q’ne”:½ŒA¯[÷&QâÐÄ6–ö'o?“Cº#É.¡ƒ$ü}?Чýá§ïÄjU%)´¥«ZÛ(ø8½><ƒ Ö¶Ò³¨`#‚Cq·ÃNsüD¦õ$¢Š%†Ù襤Ò`¯)qmœÔ.ôšcéuyÖ
Ê
string(9) "Firstname"
["lastname"]=>
string(8) "lastname"
["email"]=>
string(5) "Email"
}
And other csv files I get it nicely organized:
array(3) {
[0]=>
string(9) "firstname"
[1]=>
string(8) "lastname"
[2]=>
string(5) "email"
[3]=>
}
array(3) {
["firstname"]=>
string(9) "Firstname"
["lastname"]=>
string(8) "lastname"
["email"]=>
string(5) "email"
}
Now I don't know why I am getting the weird symbols for some, and I don't want those so if you could help me that would be great!
David
Make sure your .CSV file is saved as "comma delimited" or "tab delimited" in Excel. Cheers!
Some of yours "CSV" files are not CSV files. This ackward structure you are printing is potentially the content of a .xlsx file or some of the many other Microsoft Office 2007 formats.
If I create a blank .docx or .xlsx file and see in the hexadecimal editor I will see something like this:
00000000h: 50 4B 03 04 14 00 06 00 08 00 00 00 21 00 DD FC ; PK..........!.Ýü
00000010h: 95 37 66 01 00 00 20 05 00 00 13 00 08 02 5B 43 ; •7f... .......[C
00000020h: 6F 6E 74 65 6E 74 5F 54 79 70 65 73 5D 2E 78 6D ; ontent_Types].xm
00000030h: 6C 20 A2 04 02 28 A0 00 02 00 00 00 00 00 00 00 ; l ¢..( .........
00000040h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000050h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000060h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
Quite familiar, isn't it?
Those files are actually .zip files contenting a tree of .xml files and other resources belonging to your document.
can you try utf8_encode() on the string?
Related
PHP has a method hash_hmac that computes the HMAC signature of a given string using a given key and algorithm. But HMAC technically operates on binary data, and PHP takes all its params here as strings. How does it convert those strings to binary data?
Short answer: String encoding is just metadata attached to a lump of binary data. PHP strings are just the lump, you have to keep track of the rest.
Long answer:
PHP takes the Honey Badger approach to native string encodings, in other words, "PHP don't care". You give it a sequence of bytes, it stores them. It has no concept of encoding until you want to use a function that cares about it. Even then you need to explicitly declare the input and output encodings, otherwise PHP will go with its configured default which is usually not what anyone actually wants.
function nice_hex($in) {
return implode(' ', str_split(bin2hex($in), 2));
}
$utf8 = "You owe me €5.";
$utf16le = mb_convert_encoding($utf8, 'utf-16le', 'utf-8');
$utf16be = mb_convert_encoding($utf8, 'utf-16be', 'utf-8');
$iso88591 = mb_convert_encoding($utf8, 'iso-8859-1', 'utf-8');
$cp1252 = mb_convert_encoding($utf8, 'cp1252', 'utf-8');
var_dump(
$utf8,
nice_hex($utf8),
hash_hmac('md5', $utf8, 'foo'),
$utf16le,
nice_hex($utf16le),
hash_hmac('md5', $utf16le, 'foo'),
$utf16be,
nice_hex($utf16be),
hash_hmac('md5', $utf16be, 'foo'),
$iso88591,
nice_hex($iso88591),
hash_hmac('md5', $iso88591, 'foo'),
$cp1252,
nice_hex($cp1252),
hash_hmac('md5', $cp1252, 'foo')
);
Output:
string(16) "You owe me €5."
string(47) "59 6f 75 20 6f 77 65 20 6d 65 20 e2 82 ac 35 2e"
string(32) "7724135d91c43906f8730a26dcd76ffb"
string(28) "You owe me � 5."
string(83) "59 00 6f 00 75 00 20 00 6f 00 77 00 65 00 20 00 6d 00 65 00 20 00 ac 20 35 00 2e 00"
string(32) "f4a2347b4a1336dae1db21554c54b9e2"
string(28) "You owe me �5."
string(83) "00 59 00 6f 00 75 00 20 00 6f 00 77 00 65 00 20 00 6d 00 65 00 20 20 ac 00 35 00 2e"
string(32) "b0c1a98d8b853e6568bae513d764a029"
string(14) "You owe me ?5."
string(41) "59 6f 75 20 6f 77 65 20 6d 65 20 3f 35 2e"
string(32) "301a0fb55e23285904413323d10cc774"
string(14) "You owe me �5."
string(41) "59 6f 75 20 6f 77 65 20 6d 65 20 80 35 2e"
string(32) "fa1ee73d39e1a70fe2cde7a8c5bbf0ba"
And the reason why that all looks like it does is because:
StackOverflow uses UTF-8.
My editor uses UTF-8.
My console uses UTF-8.
The fact that PHP doesn't care about string encoding lets me produce arbitrarily-encoded trash output like the above quite easily.
Additional recommended reading: UTF-8 all the way through
Fun Fact: One of the reasons why PHP6 never ended up happening was because they wanted to include native multibyte string encoding but no one could agree on what flavor it should be. Eventually they just scrapped the whole thing and left it up to us the same as it was in PHP5.
It's just UTF-8 (for string literals).
You can put whatever encoding you want in a string, hash_hmac() doesn't use any specific encoding, just whatever encoding your string has.
Here's an example from Wikipedia using UTF-8 encoding and running a HMAC algorithm over the binary:
HMAC_MD5("key", "The quick brown fox jumps over the lazy dog") = 80070713463e7749b90c2dc24911e275
And here's the result of the equivalent PHP code, which gets the same response:
php > echo hash_hmac('md5', "The quick brown fox jumps over the lazy dog", "key");
80070713463e7749b90c2dc24911e275
I am in the progress of transferring a script from a (discontinued) windows server to our Linux one. One of the scripts I need to transfer is a connection with a MSSQL-server.
The connection with the server is established and I am able to fetch "regular" data from any of the tables, but when I execute a stored procedure, I don't receive any of the desired data. The procedure just returns false when executed.
Testing the prepared statement for errors with $stmt->errorInfo() does not show me any relevant information, it just returns error code 00000, which should indicate everything (should) work fine.
Array
(
[0] => 00000
[1] => 0
[2] => (null) [0] (severity 0) [(null)]
[3] => 0
[4] => 0
)
php
$con = new \PDO('dblib:charset=UTF-8;host=freedts;dbname=database', 'user', 'password');
/** ------------------------------------------------------**/
$sql = 'SELECT * FROM prgroepen';
$stmt = $con->prepare($sql);
if ($stmt) {
try {
$stmt->execute();
$data = $stmt->fetch(\PDO::FETCH_ASSOC);
if ($data) echo '<pre>'.print_r($data, true).'</pre>';
else var_dump($data);
}catch(\Exception $e) {
echo $e->getMessage();
}
}
/** ------------------------------------------------------**/
$SP = <<<SQL
DECLARE #return_value int,
#soort nvarchar(1),
#dagen money
EXEC #return_value = [dbo].[web_voorraadstatus] #produkt = N'ABEC24_9002', #aantal = 1, #soort = #soort OUTPUT, #dagen = #dagen OUTPUT
SELECT #soort as N'#soort', #dagen as N'#dagen'
SQL;
$stmt = $con->prepare($SP);
if ($stmt) {
try {
$stmt->execute();
$data = $stmt->fetch(\PDO::FETCH_ASSOC);
if ($data) echo '<pre>'.print_r($data, true).'</pre>';
else var_dump($data);
}catch(\Exception $e) {
echo $e->getMessage();
}
}
output
Array
(
[kode] => A
[omschrijving] => ACCESSOIRE DISPLAYS
[aeenheid] => ST
[agb] => 604006
[veenheid] => ST
[vgb] => 700011
[coefaank] =>
[coefverk] =>
[internet] => 1
[foto] => #\\serverpc\fws$\GROEPEN\A.jpg#
[vader] =>
[produkt_niveau] => 0
[bs_kode] =>
[bs_vader] =>
[web_volgorde] => 6
[pdfcataloog] =>
)
bool(false)
I also tried to call the SP in different ways, but with no avail as well.
The exact same code runs perfectly on the windows server, with the only difference is that the windows server uses the sqlsrv-driver
/** ============================== **/
/* #produkt as nvarchar(15),
/* #aantal as money,
/* #soort as nvarchar(1) output,
/* #dagen as money output
/** ============================== **/
$stmt = $con->prepare('execute web_voorraadstatus ?, ?, ?, ?');
$stmt->bindParam(1, $produkt, PDO::PARAM_STR);
$stmt->bindParam(2, $aantal, PDO::PARAM_STR);
$stmt->bindParam(3, $soort, PDO::PARAM_STR, 1);
$stmt->bindParam(4, $dagen, PDO::PARAM_STR, 10);
var_dump($stmt->execute()); # true
var_dump($soort, $dagen); # NULL, NULL
So is dblib actually able to execute stored procedures and retrieving the data returned by it?
note: the client charset is already set to UTF-8 in the FreeDTS config file
Here is a partial from the freeDTS log, it's seems I'm receiving data from the MSSQL-server just fine?
dblib.c:4639:dbsqlok(0x7fcfd8acc530)
dblib.c:4669:dbsqlok() not done, calling tds_process_tokens()
token.c:540:tds_process_tokens(0x7fcfd78d7bd0, 0x7ffe281bec38, 0x7ffe281bec3c, 0x6914)
util.c:156:Changed query state from PENDING to READING
net.c:555:Received header
0000 04 01 00 5c 00 37 01 00- |...\.7..|
net.c:609:Received packet
0000 04 01 00 5c 00 37 01 00-79 00 00 00 00 fe 01 00 |...\.7.. y.......|
0010 e0 00 00 00 00 00 81 02-00 00 00 21 00 e7 02 00 |........ ...!....|
0020 09 04 d0 00 34 06 40 00-73 00 6f 00 6f 00 72 00 |....4.#. s.o.o.r.|
0030 74 00 00 00 21 00 6e 08-06 40 00 64 00 61 00 67 |t...!.n. .#.d.a.g|
0040 00 65 00 6e 00 d1 02 00-56 00 08 00 00 00 00 90 |.e.n.... V.......|
0050 d0 03 00 fd 10 00 c1 00-01 00 00 00 |........ ....|
If you are hemmed in by the version of PHP and FreeTDS, a sort of kludge might serve depending on your performance requirements.
In broad strokes;
Create a view based on your stored procedure
query the view
drop the view
A few different approaches are discussed on this MSDN thread: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/75a686f0-2192-4c6c-bdb8-04c074b916fc/create-view-from-stored-procedure?forum=transactsql
Notably:
declare #sql_String nvarchar(4000)
set #sql_String = N'
create view dbo.Whatever as
select ''Hello World'' as Hello_World'
exec sp_executeSql #sql_String
I could be wrong but I think this is the standard behavior of DBLIB and FreeTDS, in that they have a one statement per connection rule.
To workaround open connection object for each statement - making sure you close the cursor after each fetch.
$stmt->closeCursor();
sqlsrv on Windows does not have this behaviour hence the different results across platforms.
Try to run SQL Profiler at SQL Server and see what is running and if it is generating any warnings / errors.
Could you try to execute your SP as below?
SELECT CAST(soort AS NVARCHAR(1)) as N'#soort', CAST(dagen AS MONEY) as N'#dagen'
FROM OPENQUERY([server_name],
'DECLARE #return_value int, #soort nvarchar(1), #dagen money
EXEC #return_value = db_name.[dbo].[web_voorraadstatus] #produkt = N''ABEC24_9002'', #aantal = 1, #soort = #soort OUTPUT, #dagen = #dagen OUTPUT
SELECT #soort as N''soort'', #dagen as N''dagen''
')
server_name is what is shown in
select name
from sys.servers
where server_id = 0
I am trying to convert little endian hex to big endian hex.
Example:
Little endian:
E1 31 01 00 00 9D
Big endian:
9D 00 00 01 31 E1
If numbers are in the format described than you can convert by using standard array functions.
function littleToBigEndian($little) {
return implode(' ',array_reverse(explode(' ', $little)));
}
echo littleToBigEndian('E1 31 3C 01 00 00 9B');
// Output: 9B 00 00 01 3C 31 E1
If there are no spaces for separation of numbers you need to str_split() the string instead.
function littleToBigEndian($little) {
return implode('',array_reverse(str_split($little,2)));
}
echo littleToBigEndian('E1313C0100009B');
// Output: 9B0000013C31E1
I have this ruby function:
def WhitespaceHexEncode(str)
result = ""
whitespace = ""
str.each_byte do |b|
result << whitespace << "%02x" % b
whitespace = " " * (rand(3) + 1)
end
result
end
I am trying to make the same on php, this is the code I have so far:
function WhitespaceHexEncode($str)
{
$result = "";
$whitespace = "";
for($i=0;$i<strlen($str);$i++)
{
$result = $result.$whitespace.sprintf("%02x", $str[$i]);
$whitespace = " ";
for($x=0;$x<rand(0,5);$x++)
$whitespace = $whitespace." ";
}
return $result;
}
But the PHP function doesn't show the same output as the ruby one, for example:
print WhitespaceHexEncode("test fsdf dgksdkljfsd sdfjksdfsl")
Output: 74 65 73 74 20 66 73 64 66 20 64 67 6b 73 64 6b 6c 6a 66 73 64 20 73 64 66 6a 6b 73 64 66 73 6c
--------------------------------------------------------------
echo WhitespaceHexEncode("test fsdf dgksdkljfsd sdfjksdfsl")
Output: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Can someone tell me what's wrong in the php code?
UPDATE: Fixed it using bin2hex()
The following should work as well:
<?php
function WhitespaceHexEncode($str) {
$result = '';
foreach (str_split($str) as $b) {
$bytes = $whitespace = sprintf('%02x', ord($b));
$whitespace = str_repeat(' ', (rand(0, 5) + 1));
$result .= $bytes . $whitespace;
}
return $result;
}
echo WhitespaceHexEncode('test fsdf dgksdkljfsd sdfjksdfsl');
How can I encode strings on UTF-16BE format in PHP? For "Demo Message!!!" the encoded string should be '00440065006D006F0020004D00650073007300610067006'. Also, I need to encode Arabic characters to this format.
First of all, this is absolutly not UTF-8, which is just a charset (i.e. a way to store strings in memory / display them).
WHat you have here looks like a dump of the bytes that are used to build each characters.
If so, you could get those bytes this way :
$str = utf8_encode("Demo Message!!!");
for ($i=0 ; $i<strlen($str) ; $i++) {
$byte = $str[$i];
$char = ord($byte);
printf('%02x ', $char);
}
And you'd get the following output :
44 65 6d 6f 20 4d 65 73 73 61 67 65 21 21 21
But, once again, this is not UTF-8 : in UTF-8, like you can see in the example I've give, D is stored on only one byte : 0x44
In what you posted, it's stored using two Bytes : 0x00 0x44.
Maybe you're using some kind of UTF-16 ?
EDIT after a bit more testing and #aSeptik's comment : this is indeed UTF-16.
To get the kind of dump you're getting, you'll have to make sure your string is encoded in UTF-16, which could be done this way, using, for example, the mb_convert_encoding function :
$str = mb_convert_encoding("Demo Message!!!", 'UTF-16', 'UTF-8');
Then, it's just a matter of iterating over the bytes that make this string, and dumping their values, like I did before :
for ($i=0 ; $i<strlen($str) ; $i++) {
$byte = $str[$i];
$char = ord($byte);
printf('%02x ', $char);
}
And you'll get the following output :
00 44 00 65 00 6d 00 6f 00 20 00 4d 00 65 00 73 00 73 00 61 00 67 00 65 00 21 00 21 00 21
Which kind of looks like what youy posted :-)
(you just have to remove the space in the call to printf -- I let it there to get an easier to read output=)
E.g. by using the mbstring extension and its mb_convert_encoding() function.
$in = 'Demo Message!!!';
$out = mb_convert_encoding($in, 'UTF-16BE');
for($i=0; $i<strlen($out); $i++) {
printf("%02X ", ord($out[$i]));
}
prints
00 44 00 65 00 6D 00 6F 00 20 00 4D 00 65 00 73 00 73 00 61 00 67 00 65 00 21 00 21 00 21
Or by using iconv()
$in = 'Demo Message!!!';
$out = iconv('iso-8859-1', 'UTF-16BE', $in);
for($i=0; $i<strlen($out); $i++) {
printf("%02X ", ord($out[$i]));
}