-
String Cropping
Hello, I need some help on debugging this php script. It is supposed to search a file for a name. On the page there is name||XXXX||name, and XXXX is a person's name. I am using PHP 5.2 so I can't use the reverse needle option in strstr. I winged this code out, so it's most likely not right. I want $name2 to be the string between name|| and ||name. What am I doing Wrong?
PHP Code:
$name = file_get_contents('fileThatHasaNameInIt.php');
$findme = 'name||';
$findme2 = '||name';
$pos = strpos($name, $findme);
$pos1 = strpos($name, $findme2);
$pos2=strlen($pos1)-strlen($pos);
$name2=substr($name,$pos,$pos2);
echo $name2;
-
PHP Code:
$findme = 'name||';
$findme2 = '||name';
$holder = explode($findme, $name);
$holder = explode($findme2, $holder[1]);
$name2 = $holder[0];
-
bluewalrus, it may be a good idea (as it usually is) to limit this:
explode($a,$b,2);
That returns (at most) two parts [before, after], rather than splitting it more if name|| is found again.
If you are certain that it will never be found more than once, then that is not necessary. It just makes things more predictable.
FSD, the approach above is probably what I'd write. The "best" way to do this would be to use regex if you can.
Here's a string-function only version (since explode is said to be slow):
Code:
$name = substr($name, strpos($name,$fineme)+strlen($findme),(strpos($name,$findme2,(strpos($name,$findme)+strlen($findme)))-(strpos($name,$findme)+strlen($findme))));
//I should really learn regex.
//but that was a good challenge
//note: untested... try it a few times before using it,
//or just use the much simpler explode version above
//this could also be a lot simpler if you split it onto a few lines:
$findme_end = strpos($name,$findme)+strlen($findme);
$findme2_start = strpos($name,$findme2,$findme_end);
$name = substr($name,$findme_end,$findme2_start-$findme_start);
//Also, if you have bad input this will give unexpected results. It may be best to check first that:
if (!strpos($name,$findme)||!strpos($name,$findme2,strpos($name,$findme)+strlen($findme))) {
//error
}
EDIT: Here's an interesting approach. This might actually be faster than all of the above and it's simpler in away:
Code:
$start = strpos($name,$findme)+strlen($findme);
$end = strpos($name,$findme2,$n);
$found = '';
$n=0;
while($n+$start<$end) { $found[$n] = $name[$n+$start]; $n++; }
$name = $found;
I realize that looks more complicated, but it's because "substr" is not a great tool in PHP for finding the string between two points.
You could make it prettier like this:
Code:
function stringbetween($string,$start,$end) {
$found = '';
$n=0;
while($n+$start<$end) { $found[$n] = $string[$n+$start]; $n++; }
return $found;
/////EDIT: ERROR IN THIS. SEE NEXT POST
}
$start = strpos($name,$findme)+strlen($findme);
$end = strpos($name,$findme2,$n);
$name = stringbetween($name,$start,$end);
stringbetween() should run somewhat faster than substr() for all of that.
(Sorry for giving too complex an answer here: I'm bored and trying to get used to coding with a new text editor.)
-
I used your final version because it was the cleanest. However it outputted $name as an array. An easy fix, so the entire code is:
PHP Code:
function stringbetween($string,$start,$end) {
$found = '';
$n=0;
while($n+$start<$end) { $found[$n] = $string[$n+$start]; $n++; }
return $found;
}
$name = file_get_contents('file with a name in it');
$findme = 'name||';
$findme2 = '||name';
$start = strpos($name,$findme)+strlen($findme);
$end = strpos($name,$findme2,$n);
$name = stringbetween($name,$start,$end);$i=0;
foreach($name as $key => $value){echo $name[$i]; $i++;}
HOWEVER, It appears that the page I am receiving the name from has two "name||" and "||name". It is very complicated. I need to find the second occurrence of them or else the script flags an error because two sources were found. How can I find the second occurrence and set that as $name? The script itself works perfectly nonetheless.
-
I'm not sure why that's returning an array (apparently it's converting it-- you can use [] to get characters, but not set). However, I did something nonsensical. Just replace with this:
Code:
function stringbetween($string,$start,$end) {
$found = '';
while($start<$end) { $found .= $string[$start]; $start++; }
return $found;
}
Much simpler.
As for finding the second instance, that basically doubles the complexity. This is where regex would really make things easier.
Regardless, you can do it like this:
$start = strpos($name,$findme,(strpos($name,$findme)+strlen($findme)))+strlen($findme);
(find the position of the string starting after the position of the string. the "strlen" functions are adding the length so it skips to the end of the whole marker, rather than starting to match in the middle. It's probably irrelevant, but slightly more correct and better for making sure there are no errors. It also, this way, mimics the regex function more closely.)
But that doesn't even begin to cover error correction, so I guess you could change the if to check if strpos($name,$findme,strpos($name,$findme)) AND then AFTER that you need to be sure there's another close tag.
-
I don't know if I'm doing this right, but it still does not work. No more error, just $name being null.
PHP Code:
function stringbetween($string,$start,$end) {
$found = '';
while($start<$end) { $found .= $string[$start]; $start++; }
return $found;
}
//$name = file_get_contents('afilewithaname.php');
$name = "name||hello||name blah blah blah name||hello2||name";
$findme = 'name||';
$findme2 = '||name';
$start = strpos($name,$findme,(strpos($name,$findme)+strlen($findme)))+strlen($findme);
$end = strpos($name,$findme2,$n);
$name = stringbetween($name,$start,$end);
echo $name;
I tried commenting out the file and just using a straight-up string to see if it would work. There is still no output, even though clearly it should output "hello2". Did I set this up worng? Also as far as error suppression, It wont matter right now.
-
Ah, I see it. The variable $n was used before, but then I renamed it $start.
Fix the $end = .... line ($n <-- $start).
If that doesn't fix it (it will help, at least), then I suppose we could test it to see what the value is each time.
-
Ok, the script works fine, it's just they way I am using it does not. When I use file_get_contents, Facebook (the site where I am retrieving the name from) says That I am using an incompatible web browser if I echo $name. Ugh. Is their anyway I can falsify headers or make facebook think that the php script is a legitimate browser?
-
I really have no idea what they are requiring. They are probably trying to stop just that: blocking automated requests. For example, they may require Javascript, or they may require a cookie is sent back-- to prove it is not just reading the page. You could probably try a few things and might find a way (though they'll probably block it just as quickly), and you'd probably be violating their TOS if it's something they're blocking anyway.
You could read their documentation to see if they have an "official" way to do it.
And there are also ways to do "facebook connect" (that's what I've heard it called) where you can integrate your account (and other stuff?) with it. You could make a facebook app, for example.
Of course none of that will be easy.
Now, in theory, the way you could do this is to run a real web browser and dynamically actually get the content from that. It would require something much higher level than PHP, though, or a LOT of exec() commands at the very least.
By the way, the method of grabbing the page *might* affect the way it works:
You can try using an include (if remote files are allowed).
You can try CURL.
You can try another method that is lower level (using exec(), etc) or possibly an extension/class you can find on the internet.
-
Yeah, that's the whole thing. I am making a Facebook Application where a part of the script needs to run on my server, however that same script needs to display a person's name. Facebook Connect is horrible when it comes to that because it has to render the person's name remotely and then inject an iframe on to your page containing it. It's a slow, horrible un-reliable system, and it's not applicable to what I doing. The Facebook app itself has it's own name rending software because it's being displayed through their servers, not mine, so The idea was to have an entire app page containing just the markup to display a person's name, and then grab the name inside the iframe through the php script and display it. However, they apparently block automated requests like you said. Another way I could do it is to grab the person's name in the Facebook app and then store it in a session or cookie for the iframe to grab, BUT That is agasint their Terms of Service, aka storing Personal Identifiers. They only let you store user id's which I can't translate into a name without using Facebook Connect. But what If I encoded the name somehow and stored it in a cookie, do you think they would care? I hope this spells it out for you, and maybe a possible work-around.
-
I wouldn't know. This isn't a php issue.
You could find a way to use a cookie, but doing so might get you in trouble with facebook and that would make all the effort useless.
However, possibly if you only store the cookie CLIENT side, then it would be ok. I don't know what their TOS is, but you'd never need to store it serverside. (Sessions wouldn't work, then.)