php convert string with new lines into array? - php

I am getting data from an API and the resulting string is
[RESPONSE]
PROPERTY[STATUS][0]=ACTIVE
PROPERTY[REGISTRATIONEXPIRATIONDATE][0]=2012-04-04 19:48:48
DESCRIPTION=Command completed successfully
QUEUETIME=0
CODE=200
RUNTIME=0.352
QUEUETIME=0
RUNTIME=0.8
EOF
I am trying to convert this into an array like
Array(
['PROPERTY[STATUS][0]'] => ACTIVE,
['CODE'] => 200,
...
);
So I am trying to explode it using the resulting file_get_content function with an explode like
$output = explode('=',file_get_contents($url));
But the problem is the returning values are not always returned in the same order, so I need to have it like $array['CODE'] = 200, and $array['RUNTIME'] = 0.352 however there does not seem to be any kind of new line characters? I tried \r\n, \n, <br>, \r\n\r\n in the explode function to no avail. But there is new lines in both notepad and the browser.
So my question is there some way to determine if a string is on a new line or determine what the character forcing the new line is? If not is there some other way I could read this into an array?

To find out what the breaking character is, you could do this (if $data contatins the string example you've posted):
echo ord($data[strlen('[RESPONSE]')]) . PHP_EOL;
echo ord($data[strlen('[RESPONSE]')+1]); // if there's a second char
Then take a look in the ASCII table to see what it is.
EDIT: Then you could explode the data using that newly found character:
explode(ord($ascii_value), $data);
Btw, does file() return a correct array?

Explode on "\n" with double quotes so PHP understands this is a line feed and not a backslashed n ;-) then explode each item on =

Why not just use parse_ini_file() or parse_ini_string()?
It should do everything you need (build an array) in one easy step.

Try
preg_split("/$/m", $str)
or
preg_split("/$\n?/m", $str)
for the split

The lazy solution would be:
$response = strtr($response, "\r", "\n");
preg_match_all('#^(.+)=(.+)\s*$#m', $response, $parts);
$parts = array_combine($parts[1], $parts[2]);
Gives you:
Array (
[PROPERTY[STATUS][0]] => ACTIVE
[PROPERTY[REGISTRATIONEXPIRATIONDATE][0]] => 2012-04-04 19:48:48
[DESCRIPTION] => Command completed successfully
[QUEUETIME] => 0
[CODE] => 200
[RUNTIME] => 0.8

Related

Extract dimensions from a string using PHP

I want to extract the dimension from this given string.
$str = "enough for hitting practice. The dimension is 20'X10' *where";
I expect 20'X10' as the result.
I tried with the following code to get the number before and after the string 'X. But it is returning an empty array.
$regexForMinimumPattern ='/((?:\w+\W*){0,1})\'X\b((?:\W*\w+){0,1})/i';
preg_match_all ($regexForMinimumPattern, $str, $minimumPatternMatches);
print_r($minimumPatternMatches);
Can anyone please help me to fix this? Thanks in advance.
Just remove the \b from your pattern (and append a \' in the end if you want the trailing quote):
$regexForMinimumPattern ='/((?:\w+\W*){0,1})\'X((?:\W*\w+){0,1})\'/i';
NB: \b is the meta-character for word-boundaries, you don't need it here.
Assuming that the format of the string we want is 00'X00 :
$regexForMinimumPattern ='/[0-9]{1,2}\'X[0-9]{1,2}/i';
this gives you a result like
Array ( [0] => Array ( [0] => 20'X10 ) )
So: can a simple preg_replace()do that? Perhaps...
<?php
$str = "enough for hitting practice. The dimension is 20'X10' *where";
$dim = preg_replace("#(.*?)(\d*?)(\.\d*)?(')(X)(\d*?)(\.\d*)?(')(.+)#i","$2$3$4$5$6$7", $str);
var_dump($dim); //<== YIELDS::: string '20'X10' (length=6)
You may try it out Here.

How to get file_contents from each url of an urls array

I am trying to figure out how I can return the file_contents of each url in an array(urls_array). So far the following code , using simplehtmpdom gives me just one result then the code fails to run on.....in the foreach loop.
$urlsall = 'http://php.net,
http://php.net/downloads,
http://php.net/docs.php,
http://php.net/get-involved,
http://php.net/support,
http://php.net/manual/en/getting-started.php,
http://php.net/manual/en/introduction.php,
http://php.net/manual/en/tutorial.php,
http://php.net/manual/en/langref.php,
http://php.net/manual/en/language.basic-syntax.php,
http://php.net/manual/en/language.types.php,
http://php.net/manual/en/language.variables.php,
http://php.net/manual/en/language.constants.php,
http://php.net/manual/en/language.expressions.php,
http://php.net/manual/en/language.operators.php,
http://php.net/manual/en/language.control-structures.php,
http://php.net/manual/en/language.functions.php,
http://php.net/manual/en/language.oop5.php,
http://php.net/manual/en/language.namespaces.php,
http://php.net/manual/en/language.errors.php,
http://php.net/manual/en/language.exceptions.php,
http://php.net/manual/en/language.generators.php,
http://php.net/manual/en/language.references.php,
http://php.net/manual/en/reserved.variables.php,
http://php.net/manual/en/reserved.exceptions.php,
http://php.net/manual/en/reserved.interfaces.php,
http://php.net/manual/en/context.php';
$urls_array = explode(',', $urlsall);
//var_dump ($urls_array);
foreach ($urls_array as $url)
{
$html = SimpleHtmlDom::file_get_html($url);
$title = $html->find('title',0);
echo $title->plaintext;
}
results : PHP: Hypertext Preprocessor
ERROR: An error occured, The error has been reported.
Error on Dec 18, 2015 17:16PM - file_get_contents( http://php.net/downloads): failed to open stream: Invalid argument in E:\xampp\htdocs\sitename\SimpleHtmlDom.php on line 81
What I want to do is get all the urls titles from the above foreach loop.
Like I said in my comment: By the looks of things, the most likely cause of the problem is your using explode on a string, using comma's as delimiters. However, your string contains a lot of whitespace, too, which you're not trimming. That would explain why the first URL passes without fault, but the second one fails (that url starts with a new-line character).
I'd suggest you either define an array of url's instead of a string you explode, or you trim all the urls:
$urls = array_map('trim', explode(',', $urlsall));
This calls trim for each value in the array that explode returns. However, that's a bit silly. You're hard-coding the urls to begin with, so why not write an array instead of a long string?
$urls = array(
'http://php.net',
'http://php.net/downloads',
'http://php.net/docs.php',
'http://php.net/get-involved',
'http://php.net/support',
'http://php.net/manual/en/getting-started.php',
//rest of the urls here
);
You get this error because you have in you array some line break in your array.
When you do a var_dump of your array I get :
array (size=27)
0 => string 'http://php.net' (length=14)
1 => string '
http://php.net/downloads' (length=26)
2 => string '
http://php.net/docs.php' (length=25)
3 => string '
http://php.net/get-involved' (length=29)
Why did you used an explode ?
Make directly an array to do this :
$urlsall = array(
'http://php.net',
'http://php.net/downloads',
'http://php.net/docs.php',
'http://php.net/get-involved',
'http://php.net/support',
'http://php.net/manual/en/getting-started.php',
'http://php.net/manual/en/introduction.php',
'http://php.net/manual/en/tutorial.php',
'http://php.net/manual/en/langref.php',
'http://php.net/manual/en/language.basic-syntax.php',
'http://php.net/manual/en/language.types.php',
'http://php.net/manual/en/language.variables.php',
'http://php.net/manual/en/language.constants.php',
'http://php.net/manual/en/language.expressions.php',
'http://php.net/manual/en/language.operators.php',
'http://php.net/manual/en/language.control-structures.php',
'http://php.net/manual/en/language.functions.php',
'http://php.net/manual/en/language.oop5.php',
'http://php.net/manual/en/language.namespaces.php',
'http://php.net/manual/en/language.errors.php',
'http://php.net/manual/en/language.exceptions.php',
'http://php.net/manual/en/language.generators.php',
'http://php.net/manual/en/language.references.php',
'http://php.net/manual/en/reserved.variables.php',
'http://php.net/manual/en/reserved.exceptions.php',
'http://php.net/manual/en/reserved.interfaces.php',
'http://php.net/manual/en/context.php'
);

Cutting big string into objects

I have a huge string from a server, and I want each line as an object (for later foreach loop).
This is part of the string:
1535;;34290;;teaserbanner_881.jpg;;Not allowed;;closed;;;;closed;;
1535;;34291;;teaserbanner_8832.jpg;;Not allowed;;closed;;;;closed;;
1379;;31912;;teaserbanner_844.jpg;;Allowed;;open;;;;open;;
1379;;31913;;teaserbanner_8422.jpg;;allowed;;closed;;;;closed;;
The only thing that stays the same for each line is the "closing tags"
only two options:
;;closed;;;;closed;;
;;open;;;;open;;
I was thinking that it should be the needle for explode or some regex...
The final output should be:
element[0] 1535;;34290;;teaserbanner_881.jpg;;Not allowed;;closed;;;;closed;;
element[1] 1535;;34291;;teaserbanner_8832.jpg;;Not allowed;;closed;;;;closed;;
element[2] 1379;;31912;;teaserbanner_844.jpg;;Allowed;;open;;;;open;;
element[3] 1379;;31913;;teaserbanner_8422.jpg;;allowed;;closed;;;;closed;;
The string doesn't come in "lines" it is one big line.
You can make use of preg_match_all function:
$s = <<< EOF
1535;;34290;;teaserbanner_881.jpg;;Not allowed;;closed;;;;closed;;
1535;;34291;;teaserbanner_8832.jpg;;Not allowed;;closed;;;;closed;;
1379;;31912;;teaserbanner_844.jpg;;Allowed;;open;;;;open;;
1379;;31913;;teaserbanner_8422.jpg;;allowed;;closed;;;;closed;;
EOF;
if (preg_match_all('~(.*?;;(open|closed);{4}\2;;)~', $s, $arr))
print_r($arr[1]);
OUTPUT:
Array
(
[0] => 1535;;34290;;teaserbanner_881.jpg;;Not allowed;;closed;;;;closed;;
[1] => 1535;;34291;;teaserbanner_8832.jpg;;Not allowed;;closed;;;;closed;;
[2] => 1379;;31912;;teaserbanner_844.jpg;;Allowed;;open;;;;open;;
[3] => 1379;;31913;;teaserbanner_8422.jpg;;allowed;;closed;;;;closed;;
)
Please have a look at split. split("\n", $string) will give you an array, where each entry is one line of the string.
You can use file() for this:-
$lines = file('path/to/file');
foreach($lines as $line){
//do something with $line
}
$lines is an array with each element representing a line in the file so that
var_dump($lines);
Would give something like:-
array (size=4)
0 => string '1535;;34290;;teaserbanner_881.jpg;;Not allowed;;closed;;;;closed;;' (length=68)
1 => string '1535;;34291;;teaserbanner_8832.jpg;;Not allowed;;closed;;;;closed;; ' (length=69)
2 => string '1379;;31912;;teaserbanner_844.jpg;;Allowed;;open;;;;open;; ' (length=60)
3 => string '1379;;31913;;teaserbanner_8422.jpg;;allowed;;closed;;;;closed;;' length=63)
Try using preg_split:
$array = preg_split('/(?<=;;closed;;;;closed;;|;;open;;;;open;;)(?!$)/', $string)
(?<=;;closed;;;;closed;;|;;open;;;;open;;) makes sure there are the closing tags before the point of splitting and (?!$) makes sure the string isn't split at the end.
viper7 demo
What does huge mean?
exploding() something actually huge will deplete your PHP memory.
You need to parse it old school, char by char and add them to a bucket. When your condition is met (like the 5th ; or 10th ; or whatever...), consider the bucket a proper object and handle it. But don't store it. Push it to a file, a DB or something.
If things are not that huge, use a regular expression with an 'object' format. Like:
// keep duplicating the (.*?);; until you reach your number of columns.
preg_match_all '~(.*?);;(.*?);;(.*?);;(.*?);;(.*?);;~s' // pseudo-code :)
And this will break it all into objects and properties. Which you can iterate and use.

array_unique not working as expected in php

Here is a problem.
i am exploding a list of character by new line in an array. and doing array unique on it. but it is not working as expected.
below is code:
$list = "test
ok
test
test
ok
ok
test";
$list_explode = explode("\n", $list); //exploding the characters of the list from the input
//displaying unique
array_map('trim', $list_explode);
$result = array_unique($list_explode);
print_r($result);
The result is
Array ( [0] => test [1] => ok [6] => test )
use var_dump instead of print_r and you'll see there difference between the "test"s (take a look at codepad).
your code contains \r\n as linebreaks and you're splittoing at \n, so \r is still there at all entrys except the last one.
you're already using array_map to prevent this but forgot to use the retun-value (it doesn't work by reference) in the latter code. change that line to:
$list_explode = array_map('trim', $list_explode);
after doing this, you'll get what you expect (see at codepad again).
You've failed to take into account that your string has a sequence of \r\n for the line break. In exploding you've only removed the \n portion so what your result actually looks like is:
Array ( [0] => test\r [1] => ok [6] => test )
However, the \r does not print as a visible character (even though the code sees it).
You can split multiple lines of text in two main ways:
Use $list_explode = array_map('rtrim', explode("\n", $list));
Use $list_explode = preg_split("/\r?\n/", $list);

Dealing with commas in CSV

I get a CSV data from a SOAP call in php. Unfortunately, the data may have commas in it. It is formatted correctly as in
1,name,2,lariat,3,"first, last",5,NMEA,...
I need to parse it to individual values in either php or javascript. I have browsed through threads on stack overflow and elsewhere but have not found a specific solution in php / javascript.
The approach I am currently using is
$subject = '123,name,456,lryyrt,123213,"first,last",8585,namea3';
$pattern = '/,|,"/';
$t2=preg_replace ('/,|(".*")/','$0*',$subject);
$t2=str_replace(',','*',$t2);
$t2=str_replace('*',',',$t2);
Where * is the deliminator, but the preg_replace generates an extra *. I have tried a couple of other approaches involving preg_match and other preg_ functions but did not succeed in having any kind of a clean split.
Any suggestion on how to split up CSV data that contains commas in it?
Don't attempt to do this with a regular expression. Just use str_getcsv()! The third parameter informs str_getcsv() to look for quote-enclosed fields.
$subject = '123,name,456,lryyrt,123213,"first,last",8585,namea3';
$array = str_getcsv($subject, ",", '"');
print_r($array);
// Prints:
Array
(
[0] => 123
[1] => name
[2] => 456
[3] => lryyrt
[4] => 123213
[5] => first,last
[6] => 8585
[7] => namea3
)
Just another way to convert a csv file to an associative array.
<?php
//
// Convert csv file to associative array:
//
function csv_to_array($input, $delimiter=',')
{
$header = null;
$data = array();
$csvData = str_getcsv($input, "\n");
foreach($csvData as $csvLine){
if(is_null($header)) $header = explode($delimiter, $csvLine);
else{
$items = explode($delimiter, $csvLine);
for($n = 0, $m = count($header); $n < $m; $n++){
$prepareData[$header[$n]] = $items[$n];
}
$data[] = $prepareData;
}
}
return $data;
}
//-----------------------------------
//
//Usage:
$csvArr = csv_to_array(file_get_contents('test.csv'));
?>
For JavaScript use jQuery-CSV
If you're already using jQuery, just add the jquery-csv.js module to expose the extension methods. Then just convert the CSV directly to a JavaScript array.
If you're only parsing the following will convert it to a one-dimensional array:
$.csv.toArray(csv);
If you have a multi-line CSV string the following will convert it to a two-dimensional array:
$.csv.toArrays(csv);
Note: all the different line endings are detected and split correctly using a smart regex.
The default delimiter is a double-quote (") and the default separator is a comma (,) but you can change use custom settings by specifying them in the method call.
Ex:
$.csv.toArray(csv, {
separator:';',
delimiter:"'"
});
I created the project to provide an end-to-end CSV parser written in JavaScript that takes the guesswork out of importing-exporting CSV.
Doing the heavy lifting on the client removes unnecessary load on the server and removes any unnecessary AJAX round-trips to the server.
Update:
If you're looking for a server-side solution, the library also works on Node.js.

Categories