What could cause string concatenation to fail? - php

The following code lives on one of my servers:
$curl = curl_init();
$url = "http://www.example.com/controller/action?param1=" . $value1 . "&param2=" . $value2;
$url = str_replace(" ","%20",$url);
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $url
));
$result = curl_exec($curl);
Most of the time, this works just fine. However, today in example.com's access logs, I noticed an entry where the second parameter was completely missing. Not just the value, the entire parameter. So the log line was
GET /controller/action?param1=36838242 HTTP/1.1
I can't think of any condition what would cause param2 to be completely missing from the querystring. However, obviously it happened. And there is only one block of code that makes this curl call, so this is definitely the code responsible for the access log entry.
So my question is, under what condition could part of a concatenation fail, but have the rest of the code continue running? Since the code works 99% of the time, I'd love to write it off as a fluke, but this is really bugging me.

As others have pointed out, the string concatenation cannot fail.
I'm going to guess that $value1 contains a some non-printable character that is not being properly encoded. Your str_replace is only handling spaces. You would be much safer doing something like this:
$params = array( 'param1' => $value1,
'param2' => $value2 );
$url = 'http://www.example.com/controller/action?' . http_build_query($params);
And dropping the current call to str_replace.

Related

http_build_query ignore one key

I've a URL which becomes a query string with the http_build_query function.
But I have a parametertimestamp which I cannot edit. And &times becomes a multiplication sign x.
Is there a workaround for this?
This is my array which gets passed to the http_build_query function.
$parameters = array(
"transaction_id"=>uniqid("FF-"),
"timestamp"=> time(),
"order_total"=>$_SESSION['total_price'],
"order_total_with_vat"=>$_SESSION['total_price'] * 1.21,
"order_vat"=>"21",
"payment_method"=>"ideal",
"payment_status"=>"1",
"customer_name"=>$_SESSION['customer_data']['naam'],
"customer_address"=>$_SESSION['customer_data']['address'],
"customer_city"=>$_SESSION['customer_data']['city'],
"customer_zipcode"=>$_SESSION['customer_data']['zipcode'],
"customer_country"=>$_SESSION['customer_data']['country'],
"customer_email"=>$_SESSION['customer_data']['email'],
"customer_telephone"=>$_SESSION['customer_data']['telephone'],
);
Output of url:
http://somedomain/subdir/someapi/order?transaction_id=FF-58e2451c5aea9×tamp=1491223836&order_total=156695&order_total_with_vat=189600.95&order_vat=21&payment_method=ideal&payment_status=1&customer_name=t&customer_address=t&customer_city=t&customer_zipcode=t&customer_country=t&customer_email=t%40t&customer_telephone=t&product%5B0%5D=5&product%5B1%5D=5&product%5B2%5D=5&product%5B3%5D=5&product%5B4%5D=5&product%5B5%5D=5&product%5B6%5D=5
Preferred output:
http://somedomain/subdir/someapi/order?transaction_id=FF-58e2451c5aea9&timestamp=1491223836&order_total=156695&order_total_with_vat=189600.95&order_vat=21&payment_method=ideal&payment_status=1&customer_name=t&customer_address=t&customer_city=t&customer_zipcode=t&customer_country=t&customer_email=t%40t&customer_telephone=t&product%5B0%5D=5&product%5B1%5D=5&product%5B2%5D=5&product%5B3%5D=5&product%5B4%5D=5&product%5B5%5D=5&product%5B6%5D=5
http_build_query function:
case 'POST':
curl_setopt( $curlHandler, CURLOPT_POST, true );
$url .= '?' . http_build_query( $parameters );
break;
Currently it is working correctly. The issue is that when you echo your URL the sequence &times will make your browser replace it with the multiplication symbol x. To echo it and show the correct way in the browser try this:
echo htmlspecialchars($url);
This will display the desired URL.
#Novice was right, he commented on my question:
It's just a display issue in browser but your curl data will go just like what you have shown in your preferred output , no need to add anything extra just hit and go! – Novice
When I checked the apache access.log I could see the preferred query string posted.

Google + button counts showing "0" using the Sharrre library ( Json , Php )

So checked via a phpinfo() and Safe Mode on my server is off, Curl is activated and there are no reasons for it not to work.
I also made sure Sharrre.php is in my root directory. Even included the Curlurl to the php file. Tried both absolute and relative linking. The google button with the counter shows as soon it is uploaded but not as expected because the counter shows 0 the entire time.
The culprit seems to be: $json = array('url'=>'','count'=>0);
After a few lines of other code we got this:
if(filter_var($_GET['url'], FILTER_VALIDATE_URL)){
if($type == 'googlePlus'){ //source http://www.helmutgranda.com/2011/11/01/get-a-url-google-count-via-php/
$contents = parse('https://clients6.google.com/rpc?key=AIzaSyCKSbrvQasunBoV16zDH9R33D88CeLr9gQurl=' . $url . '&count=true');
preg_match( '/window\.__SSR = {c: ([\d]+)/', $contents, $matches );
if(isset($matches[0])){
$json['count'] = (int)str_replace('window.__SSR = {c: ', '', $matches[0]);
}
}
So either the google url code is not valid anymore or... well maybe there is something wrong with the suspected culprit because:
when changed to a value higher than 0 $json = array('url'=>'','count'=>15);
It shows 15 counts as you can see. I want it to be dynamic though and get the counts I already have and update those per click.
What can be done to solve this?
In my particular case the problem was in the asignement of the URL to the Curl object.
The original script sharrre.php sets the URL by asigning it to an array element of the curl object, but this is not working and causes Google counter not retrieve any amount.
Instead, the URL must be asigned by the curl_setopt() function.
This resolved this problem in my case:
sharrre.php:
//...
$ch = curl_init();
//$options[CURLOPT_URL] = $encUrl; // <<<--- not working! comment this line.
curl_setopt_array($ch, $options);
curl_setopt($ch, CURLOPT_URL, $encUrl ); // <<<--- Yeeaa, working! Add this line.
//...
Hope this help.

Part of string missing after urldecode() in php

I have an encoded string (it is too long to be posted here). When I use different utilities for decoding the string (http://www.the-art-of-web.com/javascript/escape/) the string looks perfect after urldecode(). However, when I actually pass the string through urldecode() in my php file on my testing environment the first 100 or so characters are missing. I cannot figure out why. I have tried both urldecode and rawurldecode. If you want to see the string I am trying to process you can make a GET request against this url http://pacific-wave-7885.herokuapp.com/api/opencart the string I am working with is the "contents" value of the JSON object
What i am trying to accomplish:
I want to make a php file that calls the above api address, gets the contents from the JSON object, decodes the string and parses the code.
here is what I have tried:
function utf8_urldecode($str) {
$str = preg_replace("/%u([0-9a-f]{3,4})/i","&#x\\1;",urldecode($str));
return html_entity_decode($str,null,'UTF-8');;
}
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar\r\n"
)
);
$context = stream_context_create($opts);
$file = file_get_contents('http://pacific-wave-7885.herokuapp.com/api/opencart', false, $context);
$contents_decode = utf8_urldecode($file);
echo $contents_decode;
You can see with this code that the "contents" starts with "language->load('shipping/usps')" and is missing the first 100 or so characters of that part of the string.
I have also tried this:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://pacific-wave-7885.herokuapp.com/api/opencart");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
$data = json_decode($output, true);
$contents = $data[0]['contents'];
$contents_decode = urldecode($contents);
echo $contents_decode;
curl_close($ch);
This also produces the same result - part of the beginning of the string is missing.
to reiterate: if you grab the encoded string straight from the JSON object and use an online decoding tool the string looks great, but once it is passed through urldecode() in my php file the first part of the string is missing characters.
If anyone can see what I am missing I would be so grateful.
Just fyi: My php environment is the latest version of XAMPP with php5 and the JSON object is coming from a NODE server with express.js.
If anyone has a better idea of how I can pass php code as a string from a Node server to a PHP server and then parse it I would be open to that as well.
I'm going to make two assumptions:
It's showing up starting at language->load('shipping/usps');
You are viewing the returned string in your browser.
Good news is that you aren't missing any characters! The browser is simply misinterpreting the tags -
<?php
class ModelShippingUsps extends Model {
public function getQuote($address) {
$this->
The browser is trying to make sense of it - it doesn't know this is PHP, it thinks it is HTML. It sees < and thinks "oh cool, beginning of an HTML tag." And then it sees ? and it just tries to figure out what kind of malformed tag this is, and then it see's -> and it decides it must be an HTML comment, so it parses it as:
<!--?php
class ModelShippingUsps extends Model {
public function getQuote($address) {
$this--->
Change echo $contents_decode; to echo "<textarea>" . $contents_decode . "</textarea>" and you'll see the full string.
Why not just return the data (instead of a PHP block in the contents) and have your PHP class on the receiving end decode the JSON and complete the logic.
If you are insisting on getting the PHP block back...it might be easier to just return a JSON response from node/express and use json_decode to pull it into an array. In playing with this the only way I could make your PHP block JSON friendly was to escape it then encodeURIComponent.
<?php
$jsonString = '{
"name":"usps.php",
"version":1,
"platform":"opencart",
"contents":"%253C%253Fphp%250Aclass%2520ModelShippingUsps%2520extends...57D%250A%2509%2509%257D%250A%250A%2509%2509return%2520%2524method_data%253B%250A%2509%257D%250A%257D%250A%253F%253E",
"_id":"53c40942bddf820200000007",
"__v":0
}
';
$jsonArr = json_decode( $jsonString, true);
var_dump( urldecode( urldecode( $jsonArr["contents"] ) ) );
?>

Handling a space in a get parameter

I am using a command like
$page = file_get_contents($url);
where
$url = "http://www.site.com/search/index.cfm?tab=names&workername=firstname lastname";
When the url is typed directly in the browser chrome adds a %20 in between firstname and lastname and the website handles things properly.
However when I use $url with a space, file_get_contents grabs only results that match the firstname and isn't aware that workername = "firstname lastname"
When I explicitly add "%20" in between it returns NULL...
What's the work around?
Thanks guys!
A few problems:
I hope this is just because you quick-typed it here, but you need to have the string in single quotes.
There is no query string for the URL because you never start it with the ?, so no, neither of those variables will exist in $_GET.
You do have to redefine spaces as %20 for URLs.
$url = 'http://www.site.com/search/?tab=names&workername=firstname%20lastname';
^ ^ ^^^ ^
Edit:
It is possible that the website you're trying to query is ignoring them as GET variables. Have you tried adding this code to explicitly say it is a GET request?
$options = array(
'http' => array('method' => "GET", 'header' => "Accept-language: en\r\n")
);
$context = stream_context_create($options);
file_get_contents($url, false, $context);
You need to urlencode your text:
$fixed= urlencode($workername);
$url = 'http://www.example.com/search/?tab=names&workername='.$fixed;

php escaping when I don't need it to

I've got an issue whereby PHP is escaping where I really don't want it to in this code:
$url_ = stripslashes(((substr(strtolower($url),0,7)!="http://")? "http://".$url:$url));
$host = $this->googleDomains[mt_rand(0,count($this->googleDomains)-1)];
$target = "/search?";
$querystring = sprintf("client=navclient-auto&ch=%s&features=Rank&q=%s",
$this->CheckHash($this->HashURL($url_)),urlencode("info:".$url_));
$contents="";
$this->debugRes("host", $host);
$this->debugRes("query_string", $querystring);
$this->debugRes("user_agent", $this->userAgent);
thus producing a URL like this which causes the script to fail:
{"urls":[{"url":"hostcule.com","converted_url":"http:\/\/toolbarqueries.google.com\/search??client=navclient-auto&ch=74451333464&features=Rank&q=info%3Ahttp%3A%2F%2Fhostcule.com"}]}
How do I stop it?
Magic Quotes are Off.
Here's the $url comes from:
foreach (preg_split('#[\r\n]+#', $_POST['urls']) as $url) {
$url = trim($url);
if ($url)
$_SESSION['converted_urls'][] = array('url' => $url, 'converted_url' => $pr->GetPR($url, true, true));
}
At this stage, $_POST['urls'] looks like:
{"urls":[{"url":"hostcule.com","converted_url":"http:\/\/www.google.com\/search??client=navclient-auto&ch=74451333464&features=Rank&q=info%3Ahttp%3A%2F%2Fhostcule.com"}]}
whilst $url looks like
{"urls":[{"url":"hostcule.com","converted_url":"http:\/\/www.google.com\/search??client=navclient-auto&ch=74451333464&features=Rank&q=info%3Ahttp%3A%2F%2Fhostcule.com"}]}
There is nothing in that code that would produce the code you quote.
My suspicion is that $url already contains the garbled http\/\/, and therefore your http:// recognizing mechanism never triggers.
You need to step back and look where $url comes from. There is where your problem will be.
The code you have there doesn't do any escaping at all. You'll need to post what you do to that $url_ after this line.
use ' instead of "

Categories