Text line into an separated array with PHP [closed] - php

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 10 years ago.
I have txt file with 30 values in line separated with space.
12.09.11 0:01 16.2 16.2 16.2 72 11.2 3.1 SE 0.19 3.6 SE 15.9 15.9 15.7 761.8 0.00 0.0 0.001 0.000 20.9 46 8.9 19.8 8.65 1.1902 13 1 56.5 1
12.09.11 0:02 16.2 16.2 16.2 72 11.2 3.1 SE 0.19 4.0 SE 15.9 15.9 15.7 761.8 0.00 0.0 0.001 0.000 20.9 46 8.9 19.8 8.65 1.1903 23 1 100.0 1
12.09.11 0:03 16.2 16.2 16.2 72 11.1 3.6 SE 0.21 4.9 SE 15.4 15.9 15.2 761.8 0.00 0.0 0.002 0.000 20.9 46 8.8 19.8 8.65 1.1905 23 1 100.0 1
I'm not so good with PHP-array so i stuck with this:
<?PHP
$file_handle = fopen("data.txt", "rb");
while (!feof($file_handle) ) {
$textline = fgets($file_handle);
print $textline[0] . $textline[1]. $textline[2] . "<BR>";
}
fclose($file_handle);
?>
It gets me the output of 3 first character on line, in this case it looks like:
12.
12.
12.
But i need tottaly separated data values in arrays, so the output should look like this:
12.09.11 0:01 16.2
12.09.11 0:02 16.2
12.09.11 0:03 16.2
P.S. Also i need to avoid first 3 lines from reading, it shoudl allways start reading from 4th line.
Any tips or advice how to script it properly ? Thanx!

The below code reads a text file line by line.
<?php
$file = "/tmp/file1.txt";
$f = fopen($file, "r");
while ( $line = fgets($f, 1000) ) {
print $line;
}
?>
So, the same way, you can use:
<?php
$file = "data.txt";
$f = fopen($file, "r");
$myArray = array();
while ( $line = fgets($f) ) {
$myArray[] = explode(" ", $line);
}
print_r($myArray);
?>

Related

How to unpack a binary string consists of two bytes with a hint (LSB = version 0.01)

I'm working on unpacking a binary data for the first time, I'm doing it pretty fine but I have a part where I need to unpack two bytes with (LSB = version 0.01) (that's a hint written by someone I can't reach to), Could someone please explain that to me? and how I should do it in PHP, I have googled that first but I couldn't find anything useful out there.
<info>: 10 Bytes
offset 0 / 1 byte: SV = payload structure subversion (0x01 -> version 1.00)
offset 1 / 2 bytes: HW = HW version (LSB = version 0.01)
offset 3 / 2 bytes: FW = FW version (LSB = version 0.01)
offset 5 / 1 byte: DS = device status
offset 6 / 4 bytes: SN = 32-bit device serial number
// My solution
$sensor->hw_version = unpack('v', substr($binary_data, 5, 2))[1]; // this giving me numbers like 110
Input is a base64 string, otykgAFuAGUAAEwBQAMfCqMI6g3zA+UDBQR8AXEBiQEyAiQCPQKh/nb+SwBKAAA=
expected output something similar to this:
CR = 0xEA69
MN = 0x19
SI = 0x80
SV = 0x01
HW = 1.10 (0x006E)
FW = 1.00 (0x0064)
DS = 0x05 (bit0 = 1: Request for response with settings, bit2-bit1 = 0b10: Watchdog reset occured before this transmission)
SN = 03401234
Sensor data:
S1 <battery> = 2450 mV
S2 <solar> = 1825 mV
S3 <precipitation> = 360 (accumulative value in [0.1 mm])
S4 <air_temperature> average = 15.62 degree C.
S5 <air_temperature> min = 14.50 degree C.
S6 <air_temperature> max = 16.02 degree C.
S7 <relative_humidity> average = 72.3 %
S8 <relative_humidity> min = 71.0 %
S9 <relative_humidity> max = 73.1 %
S10 <deltaT> average = 2.55 degree C.
S11 <deltaT> min = 2.12 degree C.
S12 <deltaT> max = 2.89 degree C.
S13 <dewPoint> average = 0.59 degree C.
S14 <dewPoint> min = -1.21 degree C.
S15 <vpd> average = 1.17 kPa
S16 <vpd> min = 0.95 kPa
S17 <leaf_wetness> = 15 min.
What else should I do?
0x6E is 110 in decimal, but 0x006E depends on if you unpack it as big-endian, or little-endian. In this case you want big-endian, or the n flag to unpack.
$enc_version = "\x00\x6e";
$unpacked = unpack('n', $enc_version)[1];
$dec_version = sprintf("%.2f", $unpacked/100);
var_dump(
bin2hex($enc_version),
$unpacked,
$dec_version
);
Output:
string(4) "006e"
int(110)
string(4) "1.10"

When php OPCODE is interpreted by zend, what is really executed?

Let's say I run the following code :
function isLucky() : bool
{
for ($i = 0; $i < 50; ++$i) {
try {
if (!rand(0, 9)) {
return true;
};
throw new Exception();
} catch (Exception $e) {
}
}
}
Some software (Vulcan Logic Dumper) gets me generated opcode:
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
5 0 E > ASSIGN !0, 0
1 > JMP ->15
7 2 > INIT_FCALL 'rand'
3 SEND_VAL 0
4 SEND_VAL 9
5 DO_ICALL $3
6 BOOL_XOR ~4 $3
7 > JMPZ ~4, ->9
8 8 > > RETURN <true>
10 9 > NEW $5 :20
10 DO_FCALL 0
11 > THROW 0 $5
12* JMP ->14
11 13 E > > CATCH last 'Exception'
5 14 > PRE_INC !0
15 > IS_SMALLER_OR_EQUAL ~8 !0, 50
16 > JMPNZ ~8, ->2
14 17 > VERIFY_RETURN_TYPE
18 > RETURN null
This is nice, but is there a way to get what the system really does ?
Is this zend framework re-interpreting each token ?
Where actually are the system calls ?
Do each opcode instruction cost the same ?
When I check the generated output of a C++ program with objdump, a program is a list of instructions, and jumps are are made to a memory adress.
A dummy c++ function from a c++ file compiled with -O0 and -c objdump-ed:
0000000000000000 <_Z14dummy_functionb>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 89 f8 mov %edi,%eax
6: 88 45 fc mov %al,-0x4(%rbp)
9: 80 7d fc 00 cmpb $0x0,-0x4(%rbp)
d: 74 07 je 16 <_Z14dummy_functionb+0x16>
f: b8 01 00 00 00 mov $0x1,%eax
14: eb 05 jmp 1b <_Z14dummy_functionb+0x1b>
16: b8 00 00 00 00 mov $0x0,%eax
1b: 5d pop %rbp
1c: c3 retq
Is that the case with zend's opcode ?
For instance, assuming a simple function :
<?php
(function (){
return true;
throw new Exception();
});
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
4 0 E > > RETURN <true>
5 1* NEW $0 :4
2* DO_FCALL 0
3* THROW 0 $0
6 4* > RETURN null
Will the throw expression ever be read by something ? Or will the jump completely ignore it ?
Opcodes are executed by the Zend executor. If you want to know how it works exactly, you need to read its source files.
You will find a general presentation here:
http://blog.jpauli.tech/2015-02-05-zend-vm-executor-html/

Why is str_getcsv() stripping quotation marks within fields?

The str_getcsv() function is designed to work on a line of CSV text, not on a set of lines. I am trying to use it twice, once to split multiple lines of CSV into an array of lines, and then again on each of those. This solution was working for me, and indeed I supplied it as an answer to another question.
However, I now have a problem whereby the line "AC150AC,",service tool,845.71,-2 is returned as AC150AC,,service tool,845.71,-2, with the quotation marks removed, so the comma is now treated as a separator. In debugging that, I found that multi-line values are now also not working, and are now split in the middle despite being enclosed correctly.
How can I debug this?
$ cat csv.php
<?php
$csv = '130,TEST A 1258 (U10 001),28.66,2
"AC150AC,",service tool,845.71,-2
AL7951,SEA LION,47.19,2
T11,"Test multi-
line segments",587.36,4';
$n = str_getcsv($csv, "\n");
$r = str_getcsv($csv, "\r");
print_r($n);
print_r($r);
$ xxd csv.php
00000000: 3c3f 7068 700a 0a24 6373 7620 3d20 2731 <?php..$csv = '1
00000010: 3330 2c54 4553 5420 4120 3132 3538 2028 30,TEST A 1258 (
00000020: 5531 3020 3030 3129 2c32 382e 3636 2c32 U10 001),28.66,2
00000030: 0a22 4143 3135 3041 432c 222c 7365 7276 ."AC150AC,",serv
00000040: 6963 6520 746f 6f6c 2c38 3435 2e37 312c ice tool,845.71,
00000050: 2d32 0a41 4c37 3935 312c 5345 4120 4c49 -2.AL7951,SEA LI
00000060: 4f4e 2c34 372e 3139 2c32 0a54 3131 2c22 ON,47.19,2.T11,"
00000070: 5465 7374 206d 756c 7469 2d0a 6c69 6e65 Test multi-.line
00000080: 2073 6567 6d65 6e74 7322 2c35 3837 2e33 segments",587.3
00000090: 362c 3427 3b0a 0a24 6e20 3d20 7374 725f 6,4';..$n = str_
000000a0: 6765 7463 7376 2824 6373 762c 2022 5c6e getcsv($csv, "\n
000000b0: 2229 3b0a 2472 203d 2073 7472 5f67 6574 ");.$r = str_get
000000c0: 6373 7628 2463 7376 2c20 225c 7222 293b csv($csv, "\r");
000000d0: 0a0a 7072 696e 745f 7228 246e 293b 0a70 ..print_r($n);.p
000000e0: 7269 6e74 5f72 2824 7229 3b0a 0a rint_r($r);..
$ php csv.php
Array
(
[0] => 130,TEST A 1258 (U10 001),28.66,2
[1] => AC150AC,,service tool,845.71,-2
[2] => AL7951,SEA LION,47.19,2
[3] => T11,"Test multi-
[4] => line segments",587.36,4
)
Array
(
[0] => 130,TEST A 1258 (U10 001),28.66,2
"AC150AC,",service tool,845.71,-2
AL7951,SEA LION,47.19,2
T11,"Test multi-
line segments",587.36,4
)
The problem is that you are splitting it by end of line characters(of various types) which you don't know if they are mid line or genuine end of lines.
A fudge is to use fgetcsv() to do the work for you, so you first have to give it a file to work with. This code creates a temporary file, writes the contents to it and then rewinds the file so the read starts from the beginning...
$fh = tmpfile();
fwrite($fh, $csv);
fseek($fh, 0);
while ( $row = fgetcsv($fh)) {
print_r($row);
}
fclose($fh);
What is the result expected ? I'm not sure to understand what you want.
I guess explode() will help you ?
$csv = '130,TEST A 1258 (U10 001),28.66,2
"AC150AC,",service tool,845.71,-2
AL7951,SEA LION,47.19,2
T11,"Test multi-
line segments",587.36,4';
$n = explode("\n", $csv);
var_dump(array_map('str_getcsv', $n));

PHP ErrorException creation takes a long time

After profiling a PHP script, I found that creating an exception appears to take a huge amount of time:
%Time Real User System Calls secs/call Name
100.0 0.00 3448.05 0.00 8.89 0.00 1.81 1 0.0000 3448.0543 main
64.7 2230.28 2230.28 0.02 0.02 0.00 0.00 892 2.5003 2.5003 sleep
35.1 0.01 1211.84 0.00 8.16 0.00 1.49 1001 0.0000 1.2106 do_process
34.7 986.81 1197.34 2.59 2.60 1.18 1.18 1330 0.7420 0.9003 file_get_contents
6.1 0.00 210.53 0.00 0.01 0.00 0.01 28 0.0000 7.5191 __lambda_func
6.1 210.53 210.53 0.01 0.01 0.01 0.01 28 7.5191 7.5191 ErrorException->__construct
0.4 0.00 13.47 0.01 5.21 0.00 0.18 206 0.0000 0.0654 do_check
0.4 13.15 13.15 5.08 5.08 0.15 0.15 402 0.0327 0.0327 preg_replace
So that's 7.5 seconds of real (not CPU) time per ErrorException->__construct. I'm looking for ideas on how to improve this!
Relevant code:
set_error_handler(
create_function(
'$severity, $message, $file, $line',
'throw new ErrorException($message, $severity, $severity, $file, $line);'
)
);
$opts = array(
'http' => array(
'method' => 'GET',
'timeout' => 60
)
);
$ctx = stream_context_create($opts);
try {
$this->data = file_get_contents($url, false, $ctx);
} catch (Exception $e) {
# The set_error_handler call ensures that we arrive here on any type
# of error.
$this->data = '';
if(preg_match('/HTTP\/1.[0|1] 4[0-9][0-9] /', $e->getMessage()) == 1) {
return 404;
} else if(strpos($e->getMessage(), "php_network_getaddresses: getaddrinfo failed") !== false) {
return 1000;
} else {
$this->message = $e->getMessage();
return -1;
}
}
Even if there's no obvious answer, I'd like to understand what factors could influence the real time to be so large. My understanding is that the constructor doesn't include time for the file_get_contents call itself or the catch clause, so can't really think of a good reason (other than trying to allocate a huge amount of memory) why this should be slow.
You are using an oldschool lambda function created with a call to create_function(). Is there a reason for this? Because the way that function operates is slow. You pass it a STRING with the code of the function, but that string has to be evaluated during runtime. There is no way the opcode cache could cache that code for you.
After quite a bit more testing, the problem appears to be with how APD profiling measures the elapsed time. If I put any other statement inside the error handler before throw, the profiler counts all the elapsed time against that, as mentioned in my comment.
Therefore, I'm convinced that the high elapsed time is because the profiler actually includes elapsed time from file_get_contents.
I tried using XHProf instead, and this seems to give more correct results. At least, it shows the ErrorException->__construct as taking only minimal elapsed time.

PHP Problem reading the hex values between these addresses?

<?php
$file = 'file.dat';
$file_contents = file_get_contents($file);
for ($i = 0x000481; $i <= 0x00048B; $i++) {
print $i;
}
?>
I am creating an online file analyzer but I have a small problem. It outputs (which is the actual position the hex is in)
1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163
when it should be
44 72 48 79 64 72 61 6C 69 73 6B
which his hex for DrHydralisk (me). Can anyone help me output the latter or just have it strait output ASCII (but hex is fine, I can just convert it)?
edit
Here is an image of what I am trying to do that I think will help.
http://imgur.com/nwenA.png
Here is the file I am trying to read, its a Starcraft replay (file.SC2Replay). Just search for DrHydralisk in a hex editor and that is where I am trying to read from.
http://www.mediafire.com/?6w8wi35q3o6ix8q
It should be (if clear text is in the file):
for( $i=0x481; $i<0x48D; $i++ ) {
printf("%X ", ord($file_contents[$i]));
}
Note the loop boundaries: 0x481 .. 0x48D
Result:
44 72 20 48 79 64 72 61 6C 69 73 6B
If the file contains hexadecimal numbers, this would be impossible because you need two bytes per hex char for the ascii character value range. So what is really in the file?
Edit
After reading your file, i did:
...
$file = 'file.SC2Replay';
$file_contents = file_get_contents($file);
for( $i=0x438; $i<0x443; $i++) {
printf("%X ", ord($file_contents[$i]));
}
for( $i=0x438; $i<0x443; $i++) {
printf("%s ", $file_contents[$i]);
}
...
And it says:
72 48 79 64 72 61 6C 69 73 6B
and
D r H y d r a l i s k
You messed up the file position ;-)
Regards
rbo
EDIT:
Thanks for providing the file, helped a lot! Beleive I got it working too:
//Do binary safe file read
$filename = 'file.SC2Replay';
$file = fopen($filename, "rb");
$contents = fread($file, filesize($filename));
fclose($file);
//position 1080 - 1091
for ($i = 0x438; $i < 0x443; $i++)
echo $contents[$i];
The reasons you were probably having problems is that first of all, a binary safe file read in php automatically replaces the bytes with the correct ASCII characters, so that threw off what position you actually needed to start reading from. Intead of 1153, it starts at 1080.
Could you explain how you are using the file you read in? Because the hex equivalent of:
11531154115511561157115811591160116111621163
is:
481 482 483 484 485 486 487 488 489 48a 48b
Also, there are two php functions you may find helpful
chr(int): returns the ascii character associated with the integer provided - http://php.net/manual/en/function.chr.php
dechex(int): returns the hex value of the integer provided - http://php.net/manual/en/function.dechex.php

Categories