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'
);
Related
I recently have played around with the use of preg_replace in PHP to specifically remove a string once.
However I have a list of numbers (345, 346 and wanting to remove ", 346" for example) and I have kept on running into the same problem how it removes the whole string and leaves it empty.
Desired results are
345, 346
Removing ", 346"
Turns to
345
And also
345, 346, 347 removing ", 346"
Turns to
345, 347
Code:
$oldpost = ", ".$_GET['id'];
$newposts = preg_replace($oldpost, "", $row['posts']);
I tried this previously and haven't found anything that seems to do a better job.
In your code, you have
$newposts = preg_replace($oldpost, "", $row['posts']);
where you are actually giving the entire string itself to be replaced. Hence, it gives you an empty string because your 2nd parameter is an empty string.
You can match the exact 346(if it's present) with an optional matching of a , and replace them with empty string. So your regex would look like
/(,?\s*346(\s|,|\b))?/
Snippet:
<?php
$oldpost = "345,346,347";
$newposts = preg_replace("/(,?\s*346(\s|,|\b))?/", "$2", $oldpost);
echo $newposts,PHP_EOL;
Demo: https://3v4l.org/MeSeK
Note that above approach works fine, but the best way to solve this problem is to explode the comma separated string and unset the location in the array where have the 346 and implode it back again.
Snippet:
<?php
$oldpost = "345,346,347";
$posts = explode(",",$oldpost);
$index = array_search(346,$posts);
if($index !== false){
unset($posts[$index]);
}
$new_post = implode(",",$posts);
echo $new_post;
Demo: https://3v4l.org/qvSEN
Note that if there are multiple occurrences of 346, you can use a simple foreach to unset them.
Documentation is here for preg_replace:
https://www.php.net/manual/en/function.preg-replace.php
Try adding a value for the "limit" parameter.
limit:
The maximum possible replacements for each pattern in each subject string. Defaults to -1 (no limit).
I'm building a form that'll create a Word doc. There's a part where the user will create a list, and will separete the list lines by using the " | " (vertical bar) as a delimeter. I'm trying to explode() a string like this: "First line| Second line| Third and last line |". As you guys saw, I placed a vertival bar delimiter after the last line, that's 'cause the user will probably do this mistake, and it will generate a empty line on the list.
I'm trying to avoid this error by using something like this:
$lines = explode("|",$lines);
for($a=0;$a<count($lines);$a++)
{
if(!empty($lines[$a]) or !ctype_space($lines[$a]))
{
//generate the line inside de Word Doc
}
}
This code works when I create the string by my own while testing the code, but won't work when the string come from a Form. And keep generating a empty line list inside the Word Doc.
When I var_dump() the $lines array it shows the last key as: [2]=> string(0) ""
I'm using Laravel and the form was created with the Form:: facade.(don't know if this matter, prob not)
If you guys could help me, I'd apreciate.
Alternatively just use array_filter with the callback of trim to remove elements that are empty or contain spaces before you iterate.
<?php
$string = '|foo|bar|baz|bat|';
$split = explode('|', $string);
$split = array_filter($split, 'trim');
var_export($split);
Output:
array (
1 => 'foo',
2 => 'bar',
3 => 'baz',
4 => 'bat',
)
However you might not want to remove some empty values!
You could just trim off your pipes to begin with:
<?php
$string = '|foo|bar|baz|bat|';
$string = trim($string, '|');
$split = explode('|', $string);
var_export($split);
Output as above.
Or use rtrim.
You may want to use PHP's && (and) rather than or.
For reference, see Logical Operators.
You only want to output the line if both empty() and ctype_space() return false. With your current code, blank strings will pass your if test because ctype_space() returns false even though empty() does not. Strings made up entirely of spaces will also pass because empty() returns false even though ctype_space() does not.
To correct the logic:
if(!empty($lines[$a]) && !ctype_space($lines[$a])) { ... }
Alternatively, I'd suggest trimming white space from the string before checking empty():
$lines = explode("|",$lines);
if (!empty($lines)) {
foreach ($lines as $line) {
if (!empty(trim($line)) {
// output this line
}
}
}
Also, see 'AND' vs '&&' as operator.
I am trying to get a specific image out of a url.
So for example if www.domain.com has a
<img id="image100" src="images/dog.jpg">
I am trying to get the path from that specific img tag.
I tried two different ways:
$matches = array();
preg_match_all('/<img id="image100" (.*?)src="(.*?)"\/>/i', file_get_contents($url), $matches);
echo $matches[1];
error:
Notice: Array to string conversion
$dom = new DOMDocument;
$dom->loadHTMLFile($url);
$DOMxpath = new DOMXPath($dom);
$image = $DOMxpath->query("//*[#class='image100]");
echo $image->item(0)->getAttribute('src');
error:
Fatal error: Call to a member function item() on a non-object
Regex should look something like this :
/<img id="image100".*?src="(.*?)"/
A quick explanation of what is going on here:
. matches a single character except for new line
*? means repeat the previous token
() delimits a capture group, what you want to extract.
/ escapes the character /
? makes the previous character optional
Basically, what this says is : Look in the string for a substring that starts with
<img id="image100"
contains any number of characters afterwards then continues with src="", then match whatever is between the "".
A great tool to test your regex is: https://regex101.com/r/eB8rU8/1
Having that file_get_contents is like $img:
$img = '<img id="image100" src="images/dog.jpg">';
$resp = preg_match_all('/\<img\sid="image100"\ssrc="(.*?)"\/?\>/',$img,$result);
var_dump($result)
/* response:
array (size=2)
0 =>
array (size=1)
0 => string '<img id="image100" src="images/dog.jpg">' (length=40)
1 =>
array (size=1)
0 => string 'images/dog.jpg' (length=14)
*/
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.
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