too few arguments sprintf - php

I have done this many times before, to re-use a value passed into the sprintf() function. But this code is returning a "Warning: sprintf() [function.sprintf]: Too few arguments in..." message.
Here is the code:
$search_clause = sprintf(" (msgBody LIKE %%%1$s%% OR msgSubject LIKE '%%%1$s%%' ) ", mysql_real_escape_string($match1));
Ideally the value of $match1 will be inserted into the segment of the SQL WHERE clause shown above - twice, each wrapped by '%' characters for a wildcard search.
If $match1 = "test", the resulting string value of $search_clause would be:
(msgBody LIKE '%test' OR msgSubject LIKE '%test%' )
What is the obvious mistake I'm making??

The $s is probably getting interpreted as a variable (see variable expansion). Try using single quotes instead:
$search_clause = sprintf(' (msgBody LIKE "%%%1$s%%" OR msgSubject LIKE "%%%1$s%%" ) ', mysql_real_escape_string($match1));

Just escape the $ as \$.
$search_clause = sprintf(" (msgBody LIKE %%%1\$s%% OR msgSubject LIKE '%%%1\$s%%' ) ", mysql_real_escape_string($match1));
^ ^

Related

sprintf in php, format string which has percent signs in it

How can i go about situation when i have % marks in my string, and I also want to use placeholders. Sprintf() treat all % marks as a placeholders and therefore throws an error that not each placeholder matches with given parameters?
sprintf(
'SELECT formatDateTime(toDateTime(date_time), \'%Y%m%d\') as Ymd, count(tr_cars)
FROM hours_data
WHERE (date_time BETWEEN \'%s\' AND \'%s\') AND station_id = %d
GROUP BY Ymd',
$args['dateFrom'],
$args['dateTo'],
$root['stationId']
)
);
IDE prompt: Conversion specification is not mapped to any parameter.
php output: "debugMessage":
"sprintf(): Too few arguments"
If you need to escape a % symbol, you simply put two of them together %%:
$var = 'Awesome';
sprintf( 'This string is 100%% %s!', $var ); // Output: This string is 100% Awesome!
#Magnus Eriksson is correct though. In this particular instance, you'll want to use Prepared Statements if this is an actual query you're going to run on your database.

Checking function with spaces in it in php

I am using this query
"SELECT * FROM items WHERE itemname LIKE '%$name%'"
If $name="alex", then the query returns the correct information. But if $name="alex " with trailing whitespace, then no results are returned.
If $name="alex dude", then this is valid, but $name="alex dude " is not. I only want to remove whitespace at the end of the string.
I have written a function to clear out spaces at the end of name. This is the function.
function checkname($dataname)
{
$func_name ="";
$checker = substr($dataname, -1);
if($checker == " ")
{
$func_name = substr_replace($dataname, "", -1)
function checkname($dataname);
}
else
{
$dataname = $func_name;
}
return $dataname;
}
This gives me a PHP Parse error:
syntax error, unexpected 'function' (T_FUNCTION) in C:\inetpub\vhosts\httpdocs\compare.php on line 176`.
I don't understand why recursively calling a function is giving me an error.
Can you guys help out with this? Is there a better solution or better SQL query than I am using?
There are two reasons you'll get errors. The first reason, and the reason you're seeing the message:
Parse error: syntax error, unexpected 'function'
is that you're missing a semicolon after $func_name = substr_replace($dataname, "", -1).
function is unexpected because you haven't terminated the previous line.
If you fix that, you'll still get an error, because you're using function checkname($dataname); to do the recursive call, when it should be return checkname($dataname); If you use it the way you have it, you'll get a cannot redeclare function error.
If you want it to work recursively, it can be simplified to
function checkname($dataname) {
if (substr($dataname, -1) == " ") {
return checkname(substr_replace($dataname, "", -1));
}
return $dataname;
}
But as others have said, this does basically the same thing as trim() or rtrim().
You can do direcly in sql
"SELECT * FROM items WHERE itemname LIKE concat('%', trim('$name'), '%')"
or rtrim
"SELECT * FROM items WHERE itemname LIKE concat('%', rtrim('$name'), '%')"
You can use trim, it's PHP native function stripping whitespace from the beginning and end of a string.
$trimmed = trim(' my string ');
echo $trimmed; // 'my string'
You can find more informations regarding it in the documentation.
By default, it will remove ordinary space, tab, new line, carriage return, NUL-byte and vertical tabs.
You can also control which characters are removed at the start and end of the string by using a second parameter to the trim function as specified in the documentation.
Try
SELECT * FROM items WHERE itemname LIKE '%". trim($dataname) ."%'"
trim($string) Strip whitespace (or other characters) from the beginning and end of a string
I'm using str_replace function
$name="a l e x" ;
$abcd = str_replace (" ", "", $name);
$res=mysql_query("SELECT * FROM `name` WHERE `name` LIKE '%$abcd%'") or die(mysql_error());
while($x=mysql_fetch_array($res))
{
echo $x['name']."<br>";
}
str_replace (" ", "", $name) helps to your problem
or by using sql
"SELECT * FROM `name` WHERE `name` LIKE '%".str_replace (" ", "", $name)."%'"
and it removes all your white spaces.

Single quote with variable value in a double quote string

I have a string that looks like this:
"count( IF (my_id = 'mykey',value,100)) mykey"
However, the value 'mykey' that goes right after my_id is in a variable called $which_value;
I fail to see how I can put the $which_value so that it mantains the single quote around it.
Just add the variable inside your string:
"count( IF (my_id = '$which_value',value,100)) mykey"
You should, however, escape the value properly or use prepared statements:
$stmt = $db->prepare("SELECT count(IF (my_id = :my_value, value, 100)) mykey...");
$stmt->execute(array(
':my_value' => $which_value,
));
Or, using plain ol' mysql_ functions:
$sql = sprintf("SELECT count(IF(my_id = '%s', value, 100)) mykey...",
mysql_real_escape_string($which_value)
);
mysql_query($sql);
To include a variable in a string you can do
"count( IF(my_id = '" . $which_value . "',value,100)) mykey"
Its quite hard to make out what exactly you are looking for but this should point you in the right direction (I hope)
You can always use your variable in a double-quoted string like this
"count( IF (my_id = '{$mykey}',value,100)) {$mykey}"
Inside of double quotes variables will be parsed. There is a convenient simple method just using the variable like this:
"count( IF (my_id = '$which_value',value,100)) mykey"
More complex expressions can be wrapped in curly braces like this:
"count( IF (my_id = '{$an_array[3]}',value,100)) mykey"
You may also want to consider escaping the variable string so that it does not break or open up to exploit, the string you are creating. If your id is an integer you can either typecast the variable as an integer:
"count( IF (my_id = '" . (int)$which_value . ',value,100)) mykey"
Or use the sprintf function to insert the variable into the string:
sprintf("count( IF (my_id = '%d',value,100)) mykey", $which_value)
If you need to escape text strings then you'll want to look at escape functions specific to the database you are constructing the query for.

Get and replace quoted strings with regex

I'm trying to get strings inside a quote.
I'm using regex but i have problems with escaped quotes.
For example, i have this:
$var = "SELECT * FROM TABLE WHERE USERNAME='Carasuman'";
preg_match_all('~([\'"])(.*?)\1~s', $var, $result);
$new = preg_replace('~([\'"])(.*?)\1~s',"<#################>",$var);
The code Works perfect. I got a replaced value in $new and quoted value in $result[1]
$new = "SELECT * FROM TABLE WHERE USERNAME=<#################>";
$result[1] = "Carasuman";
My problem is when i add a scaped quote inside quotes:
$var = "SELECT * FROM TABLE WHERE USERNAME='Carasuman\'s'";
I got this:
$new = "SELECT * FROM TABLE WHERE USERNAME=<#################>'s";
$result[1] = "Carasuman\" //must be "Carasuman\'s";
How I can avoid this error and get $new and $result[1] like first example?:
$new = "SELECT * FROM TABLE WHERE USERNAME=<#################>";
$result[1] = "Carasuman\'s";
Thanks!
for the match, you're never going to get Carasuman's without the \ as a single matched element since you can have match skip over chars within a single match. its either going to grab the Carasuman or Carasuman\'sjust use str_replace to get rid of the backslash
preg_match_all('~([\'"])(.*)\1~s', $var, $result);
$result[2] = str_replace('\\','',$result[2]);
for the replace, the ? in the (.*?) group makes it ungreedy, meaning it will stop at the first match. Remove the ? in (.*?) to make it greedy, meaning it will keep going until the last match
preg_replace('~([\'"])(.*)\1~s',"<#################>",$var);
Edit
Rather than doing the str_replace after the match on $result[2], it would probably be better to just do beforehand on the initial string like:
$var = str_replace("\\'","'",$var);
preg_match_all('~([\'"])(.*)\1~s', $var, $result);
$new = preg_replace('~([\'"])(.*)\1~s',"<#################>",$var);
You still need to make your wildcard match greedy like (.*?) to (.*) in order to have the apostrophe in the name included in the match/replace instead of being counted as the terminating single quote
Why don't you do this:
$var = "SELECT * FROM TABLE WHERE USERNAME='" . mysql_real_escape_string($input) . "'";
I don't think you necessarily need to do regex. Also, mysql_real_escape_string properly escapes your inputs so you can just have $input = 'Carasuman\'s'; or $input = "Carasuman's";
To match quoted strings, you could use the regex '\'.*?(?:\\\\.[^\\\\\']*)*\'' and four double quoted strings '".*?(?:\\\\.[^\\\\"]*)*"'

Using preg_replace to back reference array key and replace with a value

I have a string like this:
http://mysite.com/script.php?fruit=apple
And I have an associative array like this:
$fruitArray["apple"] = "green";
$fruitArray ["banana"] = "yellow";
I am trying to use preg_replace on the string, using the key in the array to back reference apple and replace it with green, like this:
$string = preg_replace('|http://mysite.com/script.php\?fruit=([a-zA-Z0-9_-]*)|', 'http://mysite.com/'.$fruitArray[$1].'/', $string);
The process should return
http://mysite.com/green/
Obviously this isn’t working for me; how can I manipulate $fruitArray[$1] in the preg_replace statement so that the PHP is recognised, back referenced, and replaced with green?
Thanks!
You need to use the /e eval flag, or if you can spare a few lines preg_replace_callback.
$string = preg_replace(
'|http://mysite.com/script.php\?fruit=([a-zA-Z0-9_-]*)|e',
' "http://mysite.com/" . $fruitArray["$1"] ',
$string
);
Notice how the whole URL concatenation expression is enclosed in single quotes. It will be interpreted as PHP expression later, the spaces will vanish and the static URL string will be concatenated with whatever is in the fruitArray.

Categories