I spent almost a day for this , but did not get success.
What i want to do is, i have a binary file "data.dat"
I want to read the file contents and output it in text format in say "data.txt" in php.
I tried unpack function of php, but requires the type to be mentioned as the first argument(May be i am wrong, new to php).
$data = fread($file, 4); // 4 is the byte size of a whole on a 32-bit PC.
$content= unpack("C", $data); //C for unsigned charecter , i for int and so on...
But what if i dont know that at what place , what type of data is stored in the file that i am reading?
This function is restricting me because of the type.
I want something similar to this
$content= unpack("s", $data); //where s can denote to string
Thanks.
PHP does not have a "binary" type. Binary data is stored in strings. If you read binary data from a file, it's already stored as a string. You do not need to convert it into a string.
If the binary data already represents text in some standard encoding, you don't need to do anything as you already have a valid string. If the binary data represents some encoding, you need to know what you need to do with it, we don't know.
Related
I need to split a big DBF file using php functions, this means that i have for example 1000 records, i have to create 2 files with 500 records each.
I do not have any dbase extension available nor i can install it so i have to work with basic php functions. Using basic fread function i'm able to correctly read and parse the file, but when i try to write a new dbf i have some problems.
As i have understood, the DBF file is structured in a 2 line file: the first line contains file info, header info and it's in binary. The second line contains the data and it's plain text. So i thought to simply write a new binary file replicating the first line and manually adding the first records in the first file, the other records in the other file.
That's the code i use to parse the file and it works nicely
$fdbf = fopen($_FILES['userfile']['tmp_name'],'r');
$fields = array();
$buf = fread($fdbf,32);
$header=unpack( "VRecordCount/vFirstRecord/vRecordLength", substr($buf,4,8));
$goon = true;
$unpackString='';
while ($goon && !feof($fdbf)) { // read fields:
$buf = fread($fdbf,32);
if (substr($buf,0,1)==chr(13)) {$goon=false;} // end of field list
else {
$field=unpack( "a11fieldname/A1fieldtype/Voffset/Cfieldlen/Cfielddec", substr($buf,0,18));
$unpackString.="A$field[fieldlen]$field[fieldname]/";
array_push($fields, $field);
}
}
fseek($fdbf, 0);
$first_line = fread($fdbf, $header['FirstRecord']+1);
fseek($fdbf, $header['FirstRecord']+1); // move back to the start of the first record (after the field definitions)
first_line is the variable the contains the header data, but when i try to write it in a new file something wrong happens and the row isn't written exactly as it was read. That's the code i use for writing:
$handle_log = fopen($new_filename, "wb");
fwrite($handle_log, $first_line, strlen($first_line) );
fwrite($handle_log, $string );
fclose($handle_log);
I've tried to add the b value to fopen mode parameter as suggested to open it in a binary way, i've also taken a suggestion to add exactly the length of the string to avoid the stripes of some characters but unsuccessfully since all the files written are not correctly in DBF format. What can i do to achieve my goal?
As i have understood, the DBF file is structured in a 2 line file: the
first line contains file info, header info and it's in binary. The
second line contains the data and it's plain text.
Well, it's a bit more complicated than that.
See here for a full description of the dbf file format.
So it would be best if you could use a library to read and write the dbf files.
If you really need to do this yourself, here are the most important parts:
Dbf is a binary file format, so you have to read and write it as binary. For example the number of records is stored in a 32 bit integer, which can contain zero bytes.
You can't use string functions on that binary data. For example strlen() will scan the data up to the first null byte, which is present in that 32 bit integer, and will return the wrong value.
If you split the file (the records), you'll have to adjust the record count in the header.
When splitting the records keep in mind that each record is preceded by an extra byte, a space 0x20 if the record is not deleted, an asterisk 0x2A if the record is deleted. (for example, if you have 4 fields of 10 bytes, the length of each record will be 41) - that value is also available in the header: bytes 10-11 - 16-bit number - Number of bytes in the record. (Least significant byte first)
The file could end with the end-of-file marker 0x1A, so you'll have to check for that as well.
I am reading a BLOB from a SQL data base. The file should contain 1024 float value pairs but I have no clue how to convert them. This is my query:
$stmt = $sqlHandle->query('SELECT convert (varchar (max), convert (varbinary (max), blob)) AS dump FROM data WHERE id = 200
This gets me a String with 32842 chars, which starts like this:
0x000008044072A051E00000004072AD70A00000004072BA8F600000004072C7AE200000004072D4CCC00
I do not know how the blob was created. I only that the first pair should look similar to this after being converted:
248.23112 0.000048741
Can someone explain to me how I get the string converted?
<?php
var_dump(hexdec("0x000008044072A051E00000004072AD70A00000004072BA8F600000004072C7AE200000004072D4CCC00"));
?>
I have an array and it looks like
$a=array('HEX'=>Chr(0).Chr(1).Chr(2),'b'=>123,'c'.......);
I need to store it in text file, open in text editor and edit it.
$fwp = fopen ('edit.txt', "wb");
FWrite($fwp,var_export($a,true));
FClose ($fwp);
I see that the hex data is stored as 'HEX' => '' . "\0" . [][] ''
and it seems to be lost after load-save in text editor.
So, how to store it binary-safe in php?
You can use json format.
Checkout json_encode() function.
With binary data problem is little more complicated but it can be also solved.
You can convert them to base64 format with base64_encode.
Then everything will be stored in clear ASCII without any gibberish.
I am using PHP to read in a tab delimited CSV file and a pipe delimited TXT file. Unfortunately, I cannot get a string comparsion to work even though the characters (appear) to be exactly the same. I used trim to make sure to clean up hidden characters and I even tried type-casting to string.
Var dump shows they are clearly different but I am not sure how to make them the same?
// read in CSV file
$fh = fopen($mapping_date, 'r');
$mapping_data = fread($fh, filesize($mapping_date));
...
// use str_getcsv to put each line into an array
// get values out that I want to compare
$this_strategy = (string)trim($strategy_name);
$row_strategy = (string)trim($row3[_Strategy_Name]);
if($this_strategy == $row_strategy) { // do something }
var_dump($this_strategy);
Vardump: string(16) "Low Spend ($0.2)"
var_dump($row_strategy);
Vardump: string(31) "Low Spend ($0.2)"
Can't figure out for the life of me how to make this work.
Looks like you have the database encoded in UCS2 (assuming it's MySQL). http://dev.mysql.com/doc/refman/5.1/en/charset-unicode-ucs2.html
You can use possibly use iconv to convert the format - but there's an example in the comments on that page (but it doesn't use iconv - http://php.net/manual/en/function.iconv.php#49171 ). I've not tested it.
Alternatively, change the database field encoding to utf8_generic or ASCII or whatever the file is encoded as?
Edit: Found the actual PHP function you want: mb_convert_encoding - UCS2 is one of the supported encodings, so enable that in php ini and you're good to go.
I want to write a raw byte/byte stream to a position in a file.
This is what I have currently:
$fpr = fopen($out, 'r+');
fseek($fpr, 1); //seek to second byte
fwrite($fpr, 0x63);
fclose($fpr);
This currently writes the actually string value of "99" starting at byte offset 1. IE, it writes bytes "9" and "9". I just want to write the actual one byte value 0x63 which happens to represent number 99.
Thanks for your time.
fwrite() takes strings. Try chr(0x63) if you want to write a 0x63 byte to the file.
That's because fwrite() expects a string as its second argument. Try doing this instead:
fwrite($fpr, chr(0x63));
chr(0x63) returns a string with one character with ASCII value 0x63. (So it'll write the number 0x63 to the file.)
You are trying to pass an int to a function that accepts a string, so it's being converted to a string for you.
This will write what you want:
fwrite($fpr, "\x63");
If you really want to write binary to files, I would advise to use the pack() approach together with the file API.
See this question for an example.