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

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.

Related

Unable to echo the real value of a variable

Iam given the following variable: %4$s that outputs the text "a test" in the code.
I am trying to echo strlen('%4$s'); but it always returns 4 , while adding it as echo strlen("%4$s"); is not returning again the real value (2), which in my opinion means that for some reason, is uses the number of the variable.
My primary scope is to check if %4$s contains two or more words or to count the characters of a returned string.
At this time, %4$s , returns 'a test' in my HTML, so I m expecting an echo of %4$s to return 'a test' in PHP and a strlen of %4$s to return number 6
It looks like you are using a string format suitable for something like printf() or sprintf() and you are wanting to know the length of the 4th entered value.
Sample code:
$format = '%4$s';
$val1 = 'one';
$val2 = 'two';
$val3 = 'three';
$val4 = 'a test';
echo sprintf($format,$val1,$val2,$val3,$val4);
Which will display:
a test
And you want to know the length of that 4th value. Instead of strlen('%4$s'), you should be doing strlen($val4), for example:
echo strlen($val4);
Which will show:
6
A full example would be:
$format = '%5$d is the strlen of "%4$s"';
$val1 = 'one';
$val2 = 'two';
$val3 = 'three';
$val4 = 'a test';
echo sprintf($format,$val1,$val2,$val3,$val4,strlen($val4));
Which will display:
6 is the strlen of "a test"
Edit: It is still not very clear what you are doing even after looking at the pastebin link you posted. That said, the following is a guess that works. It uses the vsprintf() method:
$format = '%6$s is the strlen of "%4$s"';
$retArr[0] = array('post_id' => 'one',
'icon' => 'two',
'title' => 'three',
'permalink' => 'a test',
'image' => '/path/to/img.png');
$retArr[0]['len'] = strlen($retArr[0]['permalink']);
echo vsprintf($format,$retArr[0]);
And still outputs:
6 is the strlen of "a test"
Referring : http://php.net/manual/en/language.types.string.php
Note: Unlike the double-quoted and heredoc syntaxes, variables and escape sequences for special characters will not be expanded when they occur in single quoted strings.
Double quoted ΒΆ
If the string is enclosed in double-quotes ("), PHP will interpret the following escape sequences for special characters:
$
is an escape character in php and if you don't escape it correctly using "\" like "\$s" "s" will be treated as a variable "$s".
Hence you are getting count as 2
strlen returns the amount of letters in a string so that's why you are getting the number 4 instead of your string.
try : '%4'.$s
Here's an answer that will count string length (by char) and do a word count.
Note: This isn't a copy-and-paste solution, so you will need to change your code to fit.
You can get the word count easily by doing the generic rule that words are separated by spaces. Here's where a PHP function called explode() comes in. We can use that combined with count() to get the word count:
$foo = 'a test';
$wordCount = count(explode(' ', $foo));
$strLength = strlen($foo);
echo $wordCount; # will output 2
echo $strLength; # will output 6
I've seen your pastebin for your array data, you can just loop through the array to get the individual values or use $array[$key] to specify a certain value to target.

What does %S mean in PHP, HTML or XML? [duplicate]

This question already has answers here:
What does the syntax '%s' and '%d' mean as shorthand for calling a variable?
(3 answers)
Closed 11 months ago.
I'm looking at Webmonkey's PHP and MySql Tutorial, Lesson 2. I think it's a php literal. What does %s mean? It's inside the print_f() function in the while loops in at least the first couple of code blocks.
printf("<tr><td>%s %s</td><td>%s</td></tr>n", ...
with printf or sprintf characters preceded by the % sign are placeholders (or tokens). They will be replaced by a variable passed as an argument.
Example:
$str1 = 'best';
$str2 = 'world';
$say = sprintf('Tivie is the %s in the %s!', $str1, $str2);
echo $say;
This will output:
Tivie is the best in the world!
Note: There are more placeholders (%s for string, %d for dec number, etc...)
Order:
The order in which you pass the arguments counts. If you switch $str1 with $str2 as
$say = sprintf('Tivie is the %s in the %s!', $str2, $str1);
it will print
"Tivie is the world in the best!"
You can, however, change the reading order of arguments like this:
$say = sprintf('Tivie is the %2$s in the %1$s!', $str2, $str1);
which will print the sentence correctly.
Also, keep in mind that PHP is a dynamic language and does not require (or support) explicit type definition. That means it juggles variable types as needed. In sprint it means that if you pass a "string" as argument for a number placeholder (%d), that string will be converted to a number (int, float...) which can have strange results. Here's an example:
$onevar = 2;
$anothervar = 'pocket';
$say = sprintf('I have %d chocolate(s) in my %d.', $onevar, $anothervar);
echo $say;
this will print
I have 2 chocolate(s) in my 0.
More reading at PHPdocs
In printf, %s is a placeholder for data that will be inserted into the string. The extra arguments to printf are the values to be inserted. They get associated with the placeholders positionally: the first placeholder gets the first value, the second the second value, and so on.
%s is a type specifier which will be replaced to valuable's value (string) in case of %s.
Besides %s you can use other specifiers, most popular are below:
d - the argument is treated as an integer, and presented as a (signed) decimal number.
f - the argument is treated as a float, and presented as a floating-point number (locale
aware).
s - the argument is treated as and presented as a string.
$num = 5;
$location = 'tree';
$format = 'There are %d monkeys in the %s';
echo sprintf($format, $num, $location);
Will output: "There are 5 monkeys in the tree."
The printf() or sprintf() function writes a formatted string to a variable.
Here is the Syntax:
sprintf(format,arg1,arg2,arg++)
format:
%% - Returns a percent sign
%b - Binary number
%c - The character according to the ASCII value
%d - Signed decimal number (negative, zero or positive)
%e - Scientific notation using a lowercase (e.g. 1.2e+2)
%E - Scientific notation using a uppercase (e.g. 1.2E+2)
%u - Unsigned decimal number (equal to or greater than zero)
%f - Floating-point number (local settings aware)
%F - Floating-point number (not local settings aware)
%g - shorter of %e and %f
%G - shorter of %E and %f
%o - Octal number
%s - String
%x - Hexadecimal number (lowercase letters)
%X - Hexadecimal number (uppercase letters)
arg1:
The argument to be inserted at the first %-sign in the format
string..(Required.)
arg2:
The argument to be inserted at the second %-sign in the format
string. (Optional)
arg++:
The argument to be inserted at the third, fourth, etc. %-sign in
the format string (Optional)
Example 1:
$number = 9;
$str = "New York";
$txt = sprintf("There are approximately %u million people in %s.",$number,$str);
echo $txt;
This will output:
There are approximately 9 million people in New York.
The arg1, arg2, arg++ parameters will be inserted at percent (%) signs in the main string. This function works "step-by-step". At the first % sign, arg1 is inserted, at the second % sign, arg2 is inserted, etc.
Note: If there are more % signs than arguments, you must use
placeholders. A placeholder is inserted after the % sign, and consists
of the argument- number and "\$". Let see another Example:
Example 2
$number = 123;
$txt = sprintf("With 2 decimals: %1\$.2f
<br>With no decimals: %1\$u",$number);
echo $txt;
This will output:
With 2 decimals: 123.00
With no decimals: 123
Another important tip to remember is that:
With printf() and sprintf() functions, escape character is not
backslash '\' but rather '%'. Ie. to print '%' character you need to
escape it with itself:
printf('%%%s%%', 'Nigeria Naira');
This will output:
%Nigeria Naira%
Feel free to explore the official PHP Documentation

How can I get constant name and constant value in file

I have files with texts an constants. How can I get constant name and constant value. Problem is that constant value has sometime spaces. I read files with file() and then with foreach...
Example:
define('LNG_UTF-8', 'Universal Alphabet (UTF-8)');
define('LNG_ISO-8859-1', 'Western Alphabet (ISO-8859-1)');
define('LNG_CustomFieldsName', 'Custom Field');
define('LNG_CustomFieldsType', 'Type');
I already tried:
to get constant name:
$getConstant1 = strpos($mainFileArray[$i], '(\'');
$getConstant2 = strpos($mainFileArray[$i], '\',');
$const = substr($mainFileArray[$i], $getConstant1 + 2, $getConstant2 - $getConstant1 - 2);
to get constant value
$position1 = strpos($file[$i], '\',');
$position2 = strpos($file[$i], '\');');
$rest = substr($file[$i], $position1 + 3, $position2 - $position1 - 2);
but not working when is space or ','...
How can i make this always working??
A regular expression matching this would be this:
preg_match("/define\(\s*'([^']*)'\s*,\s*'([^']*)'\s*\)/i", $line, $match);
echo $match[1], $match[2];
See http://rubular.com/r/m9plE2qQeT.
However, that only works if the strings are single quoted ', don't contain escaped quotes, the strings are not concatenated etc. For example, this would break:
define('LNG_UTF-8', "Universal Alphabet (UTF-8)");
define('LNG_UTF-8', 'Universal \'Alphabet\' (UTF-8)');
define('LNG_UTF-8', 'Universal Alphabet ' . '(UTF-8)');
// and many similar
To make at least the first two work, you should use token_get_all to parse the PHP file according to PHP parsing rules, then go through the resulting tokens and extract the values you need.
To make all cases work, you need to actually evaluate the PHP code, i.e. include the file and then simply access the constants as constants in PHP.
You should use get_defined_constants() function for that. It returns an associative array with the names of all the constants and their values.

Remove quotes from start and end of string in PHP

I have strings like these:
"my value1" => my value1
"my Value2" => my Value2
myvalue3 => myvalue3
I need to get rid of " (double-quotes) in end and start, if these exist, but if there is this kind of character inside String then it should be left there. Example:
"my " value1" => my " value1
How can I do this in PHP - is there function for this or do I have to code it myself?
The literal answer would be
trim($string,'"'); // double quotes
trim($string,'\'"'); // any combination of ' and "
It will remove all leading and trailing quotes from a string.
If you need to remove strictly the first and the last quote in case they exist, then it could be a regular expression like this
preg_replace('~^"?(.*?)"?$~', '$1', $string); // double quotes
preg_replace('~^[\'"]?(.*?)[\'"]?$~', '$1', $string); // either ' or " whichever is found
If you need to remove only in case the leading and trailing quote are strictly paired, then use the function from Steve Chambers' answer
However, if your goal is to read a value from a CSV file, fgetcsv is the only correct option. It will take care of all the edge cases, stripping the value enclosures as well.
I had a similar need and wrote a function that will remove leading and trailing single or double quotes from a string:
/**
* Remove the first and last quote from a quoted string of text
*
* #param mixed $text
*/
function stripQuotes($text) {
return preg_replace('/^(\'(.*)\'|"(.*)")$/', '$2$3', $text);
}
This will produce the outputs listed below:
Input text Output text
--------------------------------
No quotes => No quotes
"Double quoted" => Double quoted
'Single quoted' => Single quoted
"One of each' => "One of each'
"Multi""quotes" => Multi""quotes
'"'"#";'"*&^*'' => "'"#";'"*&^*'
Regex demo (showing what is being matched/captured): https://regex101.com/r/3otW7H/1
trim will remove all instances of the char from the start and end if it matches the pattern you provide, so:
$myValue => '"Hi"""""';
$myValue=trim($myValue, '"');
Will become:
$myValue => 'Hi'.
Here's a way to only remove the first and last char if they match:
$output=stripslashes(trim($myValue));
// if the first char is a " then remove it
if(strpos($output,'"')===0)$output=substr($output,1,(strlen($output)-1));
// if the last char is a " then remove it
if(strripos($output,'"')===(strlen($output)-1))$output=substr($output,0,-1);
As much as this thread should have been killed long ago, I couldn't help but respond with what I would call the simplest answer of all. I noticed this thread re-emerging on the 17th so I don't feel quite as bad about this. :)
Using samples as provided by Steve Chambers;
echo preg_replace('/(^[\"\']|[\"\']$)/', '', $input);
Output below;
Input text Output text
--------------------------------
No quotes => No quotes
"Double quoted" => Double quoted
'Single quoted' => Single quoted
"One of each' => One of each
"Multi""quotes" => Multi""quotes
'"'"#";'"*&^*'' => "'"#";'"*&^*'
This only ever removes the first and last quote, it doesn't repeat to remove extra content and doesn't care about matching ends.
This is an old post, but just to cater for multibyte strings, there are at least two possible routes one can follow. I am assuming that the quote stripping is being done because the quote is being considered like a program / INI variable and thus is EITHER "something" or 'somethingelse' but NOT "mixed quotes'. Also, ANYTHING between the matched quotes is to be retained intact.
Route 1 - using a Regex
function sq_re($i) {
return preg_replace( '#^(\'|")(.*)\1$#isu', '$2', $i );
}
This uses \1 to match the same type quote that matched at the beginning. the u modifier, makes it UTF8 capable (okay, not fully multibyte supporting)
Route 2 - using mb_* functions
function sq($i) {
$f = mb_substr($i, 0, 1);
$l = mb_substr($i, -1);
if (($f == $l) && (($f == '"') || ($f == '\'')) ) $i = mb_substr($i, 1, mb_strlen( $i ) - 2);
return $i;
}
You need to use regular expressions, look at:-
http://php.net/manual/en/function.preg-replace.php
Or you could, in this instance, use substr to check if the first and then the last character of the string is a quote mark, if it is, truncate the string.
http://php.net/manual/en/function.substr.php
How about regex
//$singleQuotedString="'Hello this 'someword' and \"somewrod\" stas's SO";
//$singleQuotedString="Hello this 'someword' and \"somewrod\" stas's SO'";
$singleQuotedString="'Hello this 'someword' and \"somewrod\" stas's SO'";
$quotesFreeString=preg_replace('/^\'?(.*?(?=\'?$))\'?$/','$1' ,$singleQuotedString);
Output
Hello this 'someword' and "somewrod" stas's SO
If you like performance over clarity this is the way:
// Remove double quotes at beginning and/or end of output
$len=strlen($output);
if($output[0]==='"') $iniidx=1; else $iniidx=0;
if($output[$len-1]==='"') $endidx=-1; else $endidx=$len-1;
if($iniidx==1 || $endidx==-1) $output=substr($output,$iniidx,$endidx);
The comment helps with clarity...
brackets in an array-like usage on strings is possible and demands less processing effort than equivalent methods, too bad there isnt a length variable or a last char index

improved sprintf for PHP

Does anyone know a better implementation of sprintf in PHP? I was looking for something like the string formatting we have in python:
print "Hello %(name)s. Your %(name)s has just been created!" % { 'name' : 'world' }
# prints::: Hello world. Your world has just been created!
This is pretty handy to avoid repeating the same variables without need, such as:
sprintf("Hello %s. Your %s has just been created!", 'world', 'world');
# prints::: Hello world. Your world has just been created!
I guess is fairly easy to build this on my own, but don't wanna reinvent the wheel, if you know what I mean... but I could not find (maybe wrong search keywords) any trace of this anywhere.
If anyone can help, I appreciate.
Cheers,
You can use positional (but not named) arguments to do this, for example
printf('Hello %1$s. Your %1$s has just been created!', 'world');
A word of caution here: you must use single quotes, otherwise the dollar signs will cause PHP to try to substitute $s with the value of this variable (which does not exist).
If you want named arguments then you will have to do this with a regular expression; for example, see How to replace placeholders with actual values?.
You can repeat the same placeholder with PHP's sprintf (though it might not look as nice):
$str = sprintf('%1$s %1$s', 'yay');
// str: 'yay yay'
You can use n$ right after the % in a placeholder, where n is the argument position (so %1$s refers to the first argument (as a string), %2$s refers to the second, etc.). As you can see above, when you use placeholders that are positionally-bound, you can repeat them within the string without duplicating arguments when you call sprintf.
The following code was stolen from a post by Salathe on TalkPHP.
$szAdjective = 'fluffy';
$szNoun = 'cat';
printf('Yesterday, I saw a %s. '.
'It was a %s %s! I have '.
'never seen a %s quite so %s.',
$szNoun,
$szAdjective,
$szNoun,
$szNoun,
$szAdjective);
printf('Yesterday, I saw a %1$s. '.
'It was a %2$s %1$s! I have '.
'never seen a %1$s quite so %2$s.',
$szNoun,
$szAdjective);
The above two expressions are equivalent and will both output
"Yesterday, I saw a cat. It was a fluffy cat! I have never seen a cat quite so fluffy."
I answered this very question in another post: vsprintf or sprintf with named arguments, or simple template parsing in PHP
But this has the same format youre looking for!
This is really the best way to go imho. No cryptic characters, just use the key names!
As taken from the php site:
http://www.php.net/manual/en/function.vsprintf.php
function dsprintf() {
$data = func_get_args(); // get all the arguments
$string = array_shift($data); // the string is the first one
if (is_array(func_get_arg(1))) { // if the second one is an array, use that
$data = func_get_arg(1);
}
$used_keys = array();
// get the matches, and feed them to our function
$string = preg_replace('/\%\((.*?)\)(.)/e',
'dsprintfMatch(\'$1\',\'$2\',\$data,$used_keys)',$string);
$data = array_diff_key($data,$used_keys); // diff the data with the used_keys
return vsprintf($string,$data); // yeah!
}
function dsprintfMatch($m1,$m2,&$data,&$used_keys) {
if (isset($data[$m1])) { // if the key is there
$str = $data[$m1];
$used_keys[$m1] = $m1; // dont unset it, it can be used multiple times
return sprintf("%".$m2,$str); // sprintf the string, so %s, or %d works like it should
} else {
return "%".$m2; // else, return a regular %s, or %d or whatever is used
}
}
$str = <<<HITHERE
Hello, %(firstName)s, I know your favorite PDA is the %(pda)s. You must have bought %(amount)s
HITHERE;
$dataArray = array(
'pda' => 'Newton 2100',
'firstName' => 'Steve',
'amount' => '200'
);
echo dsprintf($str, $dataArray);
// Hello, Steve, I know your favorite PDA is the Newton 2100. You must have bought 200
I've written a small component that allow you to make name substitutions in php strings. It's called StringTemplate.
With it you can get what you want with a code like this:
$engine = new StringTemplate\Engine;
$engine->render(
'"Hello {name}. Your {name} has just been created!"',
[
'name' => 'world',
]
);
//Prints "Hello world. Your world has just been created!"
Multidimensional array value are allowed too. Hope that can help.

Categories