Link to home
Start Free TrialLog in
Avatar of weekapaug
weekapaug

asked on

PHP strings vs array errors

I will add the actual data files if needed but for now I need to see if anything is wrong with code.

I am returning results from a curl session where it looks though and tries to match any URLs in the file, so I do this.

I save the results in the curl session as follows,
file_put_contents("../textfiles/$curlResponse.txt",serialize($response));

Open in new window

(I need to save the results to a file because I will need to reference it more than once after leaving the page and I don't want to have to redundantly make curl connections when I can just use a file that was already generated earlier.)

Later on, when trying use the data, I am scanning for specific URL's so I do this...

//put the file back into a variable to work with
$response2=unserialize(trim(file_get_contents("../textfiles/$curlResponse.txt")));

Open in new window

//Find all URL's on page
preg_match_all('/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i',$response2,$match);

Open in new window

//remove duplicates
$urlResults=array_map('array_unique', $match);

Open in new window

At this point when I view the $match or the $urlResults all looks fine.  I have a list of non duplicated URLS as expected but here is where I have the problem.

Something went funky and the array ends up getting stored inside another array.  I don't know enough about the how and why it happened but I don't need my array needlessly stored inside another blank array and furthermore don't understand enough about how to access what I need without making it one clean array.
$urlResults=$urlResults[0]; 

Open in new window

I am now trying to loop over the refined results and categorize them so I did this
foreach($urlResults as $k=>$v){
         if(someCondition){
        $finalURL[]=$v;
}elseif(someOtherCondition){
	$finalUR2L[]=$v
	}
}

Open in new window

and I get this....
Uncaught Error: [] operator not supported for strings
and the weirdest part is this... remember how I said I have it stored in a file?  

There is an include on the page to use the cURL script to create the file that will be used if its NOT in existence.

If it runs the include, I get the error I have shown above.  The next time its run and all subsequent tries it works fine, and its the same exact code,file, and page!  It seems there is some issue with trying to use the data from the file immediately after creating it? Only difference is in one case it was diverted to the curl script where it creates and uses the file immediately (fails), whereas all other future requests will have no need to run through the curl include (succeeds by using the file that was created and gave an error the first time!!!)

Is there some rule about not doing anything else on a page that uses cURL?  If the file will work on try 2, why won't it work on try 1??? Its the same code, same page and same file, with the only difference being whether the cURL script was freshly run to create it, or if it bypassed the cURL function because it found the file...
Avatar of weekapaug
weekapaug

ASKER

It seems in the process of explaining my issue to EE, I clarify it to myself as well and solve my own problems but I will still give points to anyone that can simply help me understand this behavior or maybe give me an example of how to write less like a noob hack.

All I did was make the the call to the cURL script before the page that that uses it and redirect to it after it creates the file.   It won't work when accessed as an include and it makes no sense to me.

To further illustrate the oddity of using include...

I was using these lines so if the include is run directly, it could have proper values if they are delivered in the URL

$thisRecord1= $thisRecord1 = $_GET['thisRecord1'] ?? 0;
$thisRecord2= $thisRecord2 = $_GET['thisRecord2'] ?? 0;

I was assuming this meant if it is already a value, then keep it, if you find a value supplied in the URL string, then use that, and if its neither than make it zero.

So when doing this, I found the value is lost on just one of the 2 variables and I dont understand it.

On the first page where the value is set I check to see what it has...

echo "$record1";
echo "$record2";

All good, values are what they should be...

then if I do this

include(differentPage.php);

Now immediately on the included template I do this...
$thisRecord1= $thisRecord1 = $_GET['thisRecord'] ?? 0;
$thisRecord2= $thisRecord2 = $_GET['thisRecord2''] ?? 0;

and if either record is zero its supposed to exit();

When I query the values of the same variable on the include page....

I end up with

thisRecord1="correct same as before the include"
thisRecord2=0.  

If I remove the line
$thisRecord2= $thisRecord2 = $_GET['thisRecord2'] ?? 0;

I do show the proper variable for $thisRecord2... so its THERE, but sets it to zero anyway?!

It had a value properly set and displaying immediately preceding the include but it gets changed to zero when I ask for it on the include page.  Strangely, thisRecord1 stays in tact, and I have no idea why the same logic doesn't work on the other variable?
What level of PHP are you using?

You might want to deconstruct this problem into component parts.  Make sure the cURL works, then make sure the regular expression works (print out the contents of $match), then make sure the step to store the files works, etc.  As it is, you will be chasing a lot of issues at once, and we get much better results when we take things one-step-at-a-time and thoroughly test each of the steps along the way.  Some general test-driven ideas are here:
https://www.experts-exchange.com/articles/7830/A-Quick-Tour-of-Test-Driven-Development.html

Also, I have never seen this in any PHP script ever.  We just don't do that.  What do you want this statement to do?
$thisRecord1= $thisRecord1 = $_GET['thisRecord'] ?? 0;
ASKER CERTIFIED SOLUTION
Avatar of Member_2_248744
Member_2_248744
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
That function is new to php 7.0 according to what I was reading and it does work.  Also, I did test each and every part on its own and they all work individually, my problem stemmed from calling the cURL, and then asking for information about the file it produced on the same page.  

To make it work, I had to make the request to cURL, then redirect away from the page and ask for the generated the file on a different page and it worked... so all the code was fine on its own, but it wasn't playing nice together.  

So there seems to be some buggy behavior if I dont get off the cURL page.  I am still boggled that the exact same code and page works if I redirect to it, as opposed to using it in an include.
Slick812, I am guessing what you describe is what is happening.  Although in other parts of my script I was able to write a file and read it immediately on the same page but the format of the data is also different and possibly a shorter write time.  

I did consider that and tried accessing the original variable itself rather than the file and still got the error.  Something about trying to do anything with any of the variables after the cURL script was executed on the same page was making it buggy.  But running cURL on its own page and then redirecting away to a page that accessed the file it just made worked.
I have also had some what to me , was odd or at least not what I thought would work , when dealing with the NEW PHP 7 API , many times, I could spend time in web search for PHP 7 API operations for my problem, and found that things had changed in PHP 7, But it's a headache sometimes for old PHP 5 programmers like me to to try and kick my 5 code to 7 code.

? ? ?
you say -
     "then redirecting away to a page that accessed the file it just made worked."
what's with that?, does not to ME make any difference? But In PHP 7, I have to go with what works, and not what makes sense to me.

You may web search for PHP 7 CURL errors or differences?
Not sure, but I seem to remember that the default settings for cURL had changed in PHP 7, and you may now need to have alterations in the cURL defaults to not use access cURL "File" operation? But this is not something I have done, so I may be dead wrong?
...seems to be some buggy behavior...
Probably not.  This is a very good read:
https://blog.codinghorror.com/the-first-rule-of-programming-its-always-your-fault/

If you want me to show you how to do this, just send me the URL.  You can find my email in my profile here at E-E, but to save you time, it's Ray.Paseur [at] Gmail.com

And in the spirit of good humor,...
User generated image
haha Ray! I do take the blame, after all computers only do what you tell them, so you can't blame them if you instruct them to do something wrong!  Thanks for the offer to help, but I do have it working.  While I'm sure it could be rewritten in a way to not require a redirect away from the curl script, I am more interested in understanding WHY this is necessary.  After working with coldfusion so long, I'm realizing php is alot more finicky with datatypes, strings, arrays, etc.  Coldfusion pretty much has one way to ask, or you're wrong and get an error code, but php has 100 ways to ask the same thing, and of course if you don't choose the right way to ask, it won't respond with what you expect either!
So true.  This is the grumpy programmer's lament, and he's mostly right.  PHP's a language that has grown by topsy.
https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/

In contrast, Ruby-on-Rails does everything by convention, not by configuration.  You can build a lot faster in ROR.

Some efforts to bring more convention to PHP are introduced in the Laravel framework, where there's just one way to do most things (thank goodness).
I have heard  alot of good things about the Ruby/Python setup.  I will give that a try at some point too.  I grew tired of asking about  problems in coldfusion only to hear crickets chirping, or the odd stares when someone asked what language I programmed in and I answered coldfusion...
Yeah, CF has kind of gone the way of the dinos.  I expect PHP will someday, too.  But for now it's got a lot of throw-weight because of WordPress, Laravel, Drupal, Joomla, etc.