sprintf warning - encoding issue - php

I'm using the following code to find all properties for a user and in turn delete them. My problem is that I'm getting a warning: Warning: sprintf(): Too few arguments for each of the properties.
However, when I manually enter the $user_id for the delete string as first_last%%40ourwiki.com it works!
Seems like sprintf requires double '%' but not sure why. Is there a way to get around this? Also, I'm using the same variable for file_get_contents and this works fine.
The Code:
$user="first_last#ourwiki.com";
$user_id=str_replace(array('#', '#'), array('%40', '%23'), $user);
print $user_id;
$url=("http://admin:password#172.16.214.133/#api/users/=$user_id/properties");
$xmlString=file_get_contents($url);
$delete = "http://admin:password#172.16.214.133/#api/users/=$user_id/properties/%s";
$xml = new SimpleXMLElement($xmlString);
function curl_fetch($url,$username,$password,$method='DELETE')
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch,CURLOPT_USERPWD,"$username:$password");
return curl_exec($ch);
}
foreach($xml->property as $property) {
$name = $property['name'];
$name2=str_replace(array('#', '#'), array('%40', '%23'), $name);
print $name2;
curl_fetch(sprintf($delete, $name2),'admin','password');
}
Thanks in advance!

% is a special character in sprintf(). So you have to escape all % before processing it, %% is a literal %s.
$delete = str_replace("http://admin:password#172.16.214.133/#api/users/=$user_id/properties/", '%', '%%').'%s';
You do not have to use sprintf here, you can use the concatenation operator too, like:
$delete = "http://admin:password#172.16.214.133/#api/users/=$user_id/properties/";
curl_fetch( $delete . $name2, 'admin', 'password' );

Related

PHP curl_setopt : Variable Not working in place of URL string

I use CURL in php, and I use CURL something like this
$url = "http://exampledomain.com";
$smsURL = $url;
$curl = curl_init();
curl_setopt ($curl, CURLOPT_URL, $smsURL);
curl_exec ($curl);
curl_close ($curl);
This is not working, but if I wrote "http://exampledomain.com" in place of "$smsURL" at curl_setopt (); It will work fine. Where is issue in my code? did I miss something?
Original Code
$url = $this->conf['sms_getway_url'];
$url .= '&recipient=' . $_POST['txt_customer_contact_no'];
$url .= '&sender=' . strtoupper($saloon_info['saloon_name']);
$url .= '&is_payor=' . $this->conf['sms_is_payor'];
$url .= '&pay_amount=' . $this->conf['sms_pay_amount'];
$url .= '&token=5ce7467e9ec045cbbac448ba5a422a02';
//$url .= '&customer_num=' . $this->conf['sms_customer_num'] . $saloon_id;
$url .= '&customer_num=' . $this->conf['sms_customer_num'];
$appointment_time = date('H:i', strtotime($app_start_time));
$employee_name = $_POST['hdn_selected_employee_name']; //$value['id_employee'];
//$sms_msg = "Hey. Recalling that I await tomorrow at. " . $appointment_time . " Regards " . $employee_name . ", " . $saloon_name . ". ";
$sms_msg = t('msg_sms_book_appointment', array('%emp_name' => $employee_name, '%saloon_name' => $_POST['hdn_selected_saloon_name'], '%time' => $appointment_time));
$url .= '&sms_msg=' . $sms_msg;
$smsURL = $url;
$curl = curl_init();
curl_setopt ($curl, CURLOPT_URL, $smsURL);
curl_exec ($curl);
curl_close ($curl);
Thanks
You compose the URL from pieces but you don't encode the values properly. There are characters that have special meaning in URLs (/, ?, &, =, %, , + and a few more). They have to be encoded when they appear in the values from the query string, in order to retain their literal meaning.
PHP helps you for this goal with function urlencode() that can be used to encode each value individually when you create a query string. Something like this:
$url = $this->conf['sms_getway_url'];
$url .= '&recipient=' . urlencode($_POST['txt_customer_contact_no']);
$url .= '&sender=' . urlencode(strtoupper($saloon_info['saloon_name']));
...
But, because this is a tedious work, it also provides an easier method. Put all the values you need into an array, using the names of the variables as keys, then pass the array to function http_build_query(). There is no need to call urlencode() any more; http_build_query() takes care of it. Also it puts ampersands (&) between the variables and equals (=) where they belong.
The code is like this:
$url = $this->conf['sms_getway_url'];
// Prepare the values to put into the query string
$vars = array();
$vars['recipient'] = $_POST['txt_customer_contact_no'];
$vars['sender'] = strtoupper($saloon_info['saloon_name']);
$vars['is_payor'] = $this->conf['sms_is_payor'];
$vars['pay_amount'] = $this->conf['sms_pay_amount'];
$vars['token'] = '5ce7467e9ec045cbbac448ba5a422a02';
$vars['customer_num'] = $this->conf['sms_customer_num'];
$appointment_time = date('H:i', strtotime($app_start_time));
$employee_name = $_POST['hdn_selected_employee_name'];
$sms_msg = t('msg_sms_book_appointment', array(
'%emp_name' => $employee_name,
'%saloon_name' => $_POST['hdn_selected_saloon_name'],
'%time' => $appointment_time,
));
$vars['sms_msg'] = $sms_msg;
// Now, the magic comes into place
$smsURL = $url.'?'.http_build_query($vars);
$curl = curl_init();
curl_setopt ($curl, CURLOPT_URL, $smsURL);
if (! curl_exec ($curl)) {
// Something went wrong. Check the status code (at least)
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
// Do something here.
// If $code >= 500 then the remote server encountered an internal error
// retry later or ask them to fix it
// If 400 <= $code < 500 then there is a problem with the request:
// maybe the resource is not there (404, 410)
// or you are not allowed to access it (403)
// or something else.
echo('Failure sending the SMS. HTTP status code is '.$code."\n");
}
curl_close ($curl);
Check the list of HTTP status codes for more details.

CURL POSTFIELDS to contain "&" character

I have working SMS sending over gateway using CURL method.
But If I include this character "&" in my message text area, it will send the message before this character only.
So how I could fix it to send messages including this character normally.
here is my code:
$from = "Gateway_username"; // SMS username
$token = "Gateway_password"; // SMS password
$option = $_REQUEST["option"];
$text = $_REQUEST["BulkSMS1__messageTextBox"];
if ($text == "") { } else {
$url = "http://awaljawaly.awalservices.com.sa:8001/Send.aspx";
$postfields = array ("REQUESTTYPE" => "SMSSubmitReq",
"Username" => "$from", "Password" => "$token", "MOBILENO" => "$d_mobile", "MESSAGE" => "$text");
if (!$curld = curl_init()) {
echo "Could not initialize cURL session.";
exit;
}
curl_setopt($curld, CURLOPT_POST, true);
curl_setopt($curld, CURLOPT_POSTFIELDS, $postfields);
curl_setopt($curld, CURLOPT_URL, $url);
curl_setopt($curld, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($curld);
curl_close ($curld);
preg_match("/(.*)/",$output, $out);
}
This is a sample message:
Our Address: H&R Center.
Thanks in advance.
I have used this to fix my issue:
$text = str_replace('&', '%26', $_REQUEST["BulkSMS1__messageTextBox"]);
You would want to encode the characters:
http://www.clockworksms.com/blog/the-gsm-character-set/
With this, try using:
utf8_encode()
The reason for this is that you're encoding for a mobile device, not a website, so using url encode will not work, compared to utf8 encode.
See urlencode() -> http://php.net/manual/en/function.urlencode.php
<?php
$text = urlencode($_REQUEST["BulkSMS1__messageTextBox"]);
?>
I have used this to fix my issue:
$text = str_replace('&', '%26', $_REQUEST["BulkSMS1__messageTextBox"]);

php strange looping problem

Sorry for the long code, I'm really losing it.
This code is supposed to get a list of urls through POST, in a textarea with breaklines between each url. The script should download each url, go through the html and take some links, then go in those links, get some data and echo it out.
For some reason, visually it looks as if I'm running getDetails() only once, as I'm getting only one set of results.
I have checked multiple times if the foreach loop takes each url separately and that part is working
Can anyone spot the problem?
require_once('simple_html_dom.php');
function getDetails($html) {
$dom = new simple_html_dom;
$dom->load($html);
$title = $dom->find('h1', 0)->find('a', 0);
foreach($dom->find('span[style="color:#333333"]') as $element) {
$address = $element->innertext;
}
$address = str_replace("<br>"," ",$address);
$address = str_replace(","," ",$address);
$title->innertext = str_replace(","," ",$title->innertext);
if ($address == "") {
$exp = explode("<strong><strong>",$html);
$exp2 = explode("</strong>",$exp[1]);
$address = $exp2[0];
}
echo $title->innertext . "," . $address . "<br>";
}
function getHtml($Url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $Url);
curl_setopt($ch, CURLOPT_REFERER, "http://www.google.com/");
curl_setopt($ch, CURLOPT_USERAGENT, "MozillaXYZ/1.0");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
function getdd($u) {
$html = getHtml($u);
$dom = new simple_html_dom;
$dom->load($html);
foreach($dom->find('a') as $element) {
if (strstr($element->href,"display_one.asp")) {
$durls[] = $element->href;
}
}
return $durls;
}
if (isset($_POST['url'])) {
$urls = explode("\n",$_POST['url']);
foreach ($urls as $u) {
$durls2 = getdd($u);
$durls2 = array_unique($durls2);
foreach ($durls2 as $durl) {
$d = getHtml("http://www.example.co.il/" . $durl);
getDetails($d);
}
}
}
You're only assigning the last element in the loop, it looks like. You'll need to concatenate. Something like $address .= $element->innertext; inside the loop (note the .= instead of =).
edit: unless I'm mistaking what it's supposed to be doing. I think I may've been focusing on the wrong part of the code.
When you use DOMDocument on html you load it with $dom->loadHTMLFile() or $dom->loadHTML() you should also call libxml_use_internal_errors(true) before hand so that it will not crash because of improperly formatted html.

PHP - Failed to open stream with URL containing variable

I'm trying to use file_get_contents but it tells me failed to open stream.
My code:
$user="first_last#ourwiki.com";
$user_id=str_replace(array('#', '#'), array('%40', '%23'), $user);
print $user_id;
$url=('http://admin:password#172.16.214.133/#api/users/=$user_id/properties');
$xmlString=file_get_contents($url);
This is what I get when I try to run it:
Warning:
file_get_contents(http://...#172.16.214.133/#api/deki/users/=$user_id/properties):
failed to open stream: HTTP request
failed! HTTP/1.1 500 Internal Server
Error
However, if I manually type in the $user_id first_last%40ourwiki.com then it works! What am I doing wrong? Shouldn't I be able to just use the variable name?
Remaining code:
$delete = "http://admin:password#172.16.214.133/#api/users/=$user_id/properties/%s";
$xml = new SimpleXMLElement($xmlString);
function curl_fetch($url,$username,$password,$method='DELETE')
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch,CURLOPT_USERPWD,"$username:$password");
return curl_exec($ch);
}
foreach($xml->property as $property) {
$name = $property['name'];
$name2 =str_replace(array('#', '#'), array('%40', '%23'), $name);
print $name2;
curl_fetch(sprintf($delete, $name2),'admin','password');
}
Variables contained in single-quoted strings are not interpreted.
You could do this:
"http://admin:password#172.16.214.133/#api/users/=$user_id/properties"
But a better habit is to do this:
'http://admin:password#172.16.214.133/#api/users/=' . $user_id . '/properties'
or this:
"http://admin:password#172.16.214.133/#api/users/=" . $user_id . "/properties"
or this:
sprintf("http://admin:password#172.16.214.133/#api/users/=%s/properties", $user_id)
The faster is with single-quoted strings, because php doesn't try to find variables in them.
This is because you have used single quotes. The content within single quotes is not parsed, so:
echo '$test';
won't display the value of the $test variable, but just the "$test" string. You can use double quotes instead, but anyway this is the best way to do it:
$url=('http://admin:password#172.16.214.133/#api/users/='.$user_id.'/properties');
Special characters such as \n, \t or \r also won't be parsed in single quotes.

Encode portion of path using PHP

I need to encode only part of the $delete path. Only the # in the email address and # in the property. I know how to use urlencode for the whole thing but not on just that. The way it works, is it loops through to get the properties and most of them include # in the name. Anyone who can help modify so that this works would be greatly appreciated!
The delete:
$delete = "http://admin:12345#192.168.245.133/#api/deki/DELETE:users/$user_id/properties/%s";
Here you can see $user_id this will be an email address BUT the # symbol needs to be encoded.
The properties which follow at the very end, has a # within the name, this needs to also be encoded. For example, one property name userprofile#external.created_date
Here is the code so far:
<?php
$user_id="john_smith#ourwiki.com";
$url=('http://admin:12345#192.168.245.133/#api/deki/users/=john_smith#ourwiki.com/properties');
$xmlString=file_get_contents($url);
$delete = "http://admin:12345#192.168.245.133/#api/deki/DELETE:users/$user_id/properties/%s";
$xml = new SimpleXMLElement($xmlString);
function curl_fetch($url,$username,$password,$method='DELETE')
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); // returns output as a string instead of echoing it
curl_setopt($ch,CURLOPT_USERPWD,"$username:$password"); // if your server requires basic auth do this
return curl_exec($ch);
}
foreach($xml->property as $property) {
$name = $property['name']; // the name is stored in the attribute
curl_fetch(sprintf($delete, $name),'admin','12345');
}
?>
Have you tried this? str_replace($string, array('#', '#'), array('%40', '%23'));
The urlencode function does not allow you to limit it to a subset of characters.

Categories