Best way to do string format in PHP - php

I have following python code to format the string,
endpoint = '/uri/{id}'
params = {'id': xxxx}
endpoint.format(**params)
which is given me a following result,
'/uri/xxxx'
I need to develop a function in PHP which is doing the same thing, and I found a question related this but still I’m not satisfy with that.
What would be the best way to do this kind of a thing with PHP?
Thanks in advance

Maybe, something like this will satisfy your needs:
function sformat($template, $params) {
return str_replace(
array_map(function($v){return '{'.$v.'}';},array_keys($params)),
$params,
$template
);
}
echo sformat('/uri/{action}/{id}', $params = array(
'id'=>'23',
'action'=>'open'
));

Related

Alternative for eval() -PHP

i am trying to implement URL mapping in PHP. I have a json file which stores the url and functions which is to execute when that link is requested. I was using eval() but then i came across this
Kepp the following Quote in mind:
If eval() is the answer, you're almost certainly asking the wrong
question. -- Rasmus Lerdorf, BDFL of PHP
now i am thinking is their any other(better) way to do it.
My json file looks like this.
{
"bw/":"main()",
"bw/login":"login()"
}
and my loadPage function look like this.
function loadPage($url){ //$url = 'bw/'
$str = file_get_contents('urls.json');
$this->link = json_decode($str, true);
$url = ltrim($url,"/");
$key = $this->link[$url];
eval("$key;");
}
EDIT:
i defined $this->link in my code
A slight tweak to your JSON to allow you to call the function dynamically would make it easier, just remove the brackets so it would look like...
{
"bw/":"main",
"bw/login":"login"
}
and then call it using...
function loadPage($url){ //$url = 'bw/'
$url = ltrim($url,"/");
$key = $this->link[$url];
$key();
}
A little better way is changing eval() to:
if (function_exists($key)) {
return $key();
}
return default();
and you might create a function "default" to show an error 404 or default page when function doesn't exists.

How to transform a php $string into a $string() function call?

My current code:
$operation = "alienFunction";
switch($operation){
case "alphaFunction":
alphaFunction();
break;
case "betaFunction":
betaFunction();
break;
case "alienFunction":
alienFunction($kidsPerPlanet, $planet);
break;
Ok, I have a big list of functions. Some functions have parameters and some have not. The $operation is received from a $_POST variable. I want to do something like this:
$operation = "alphafunction";
$operation();
Or
$operation = "alienFunction";
$operation($kidsPerPlanet, $planet);
As already written in the comments you are looking for call_user_func_array(). Just use it like this:
call_user_func_array($functionName, $argumentArray);
But since you don't know which function you call with which parameters, just define an array and then use the code above, e.g.
$arguments = [
"alphaFunction" => [],
"betaFunction" => [],
"alienFunction" => [$kidsPerPlanet, $planet],
];
call_user_func_array($functionName, $arguments[$functionName]);
Excellent.
Thanks, guys. For functions with no parameters, it's working perfectly.
I'm trying this now:
$userInfo = MySQL_FETCH_ARRAY( MySQL_QUERY( ($autoAuth) ) );
CALL_USER_FUNC_ARRAY($operation, $userInfo);
Inside of one of functions, I have this piece of code inserted into HTML:
ECHO "<p>" . VAR_DUMP($userInfo) . "</p>";
And the result gives me "string(2) "25".
I'm new here. So I don't know what to do. For sure, my question is answered. Now I know how to use a string to call a function. Should I close this, select the best answer and create another question? Should I let it open, while my WHOLE problem is solved? Or should I close it and still comment here to get feedback?
Thanks a lot. I'm loving this. I wish that I can contribute as soon as possible too. :)

Cut some word from php available?

Cut some word from php available ?
First access to page for example
www.mysite.com/test.php?ABD_07,_oU_876.00/8999&message=success
From my php code, i will get $curreny_link_redirect = test.php?ABD_07,_oU_876.00/8999&message=success
And i want to get $curreny_link_redirect_new = test.php?ABD_07,_oU_876.00/8999
( Cut &message=success )
How can i do ?
<?PHP
$current_link = "$_SERVER[REQUEST_URI]";
$curreny_link_redirect = substr($current_link,1);
$curreny_link_redirect_new = str_replace('', '&message=success', $curreny_link_redirect);
echo $curreny_link_redirect_new;
?>
Your str_replace call is inverse of what it should be. What you want to replace should be the first parameter, not the second.
//Wrong
$curreny_link_redirect_new = str_replace('', '&message=success', $curreny_link_redirect);
//Right
$curreny_link_redirect_new = str_replace('&message=success','', $curreny_link_redirect);
While simple way to do this is to use regex (or even static with str_replace()), I recommend to use built-in functions for url handling. This may be useful when working with complex parameters or multiple parameters:
$data = 'www.mysite.com/test.php?ABD_07,_oU_876.00/8999&message=success';
$url = parse_url($data);
parse_str($url['query'], $url['query']);
//now, do something with parameters:
unset($url['query']['message']);
$url['query'] = http_build_query($url['query']);
$url = http_build_url($url);
-please, note, that http_build_url() is a PECL function (pecl_http to be precise). The way above may look more complex, but it has benefits - first, as I've already mentioned, this will be easy to modify for working with complex parameters or multiple parameters. Second, it will produce valid url - i.e. encode such things as slashes, spaces, e t.c. - in result. Thus, result will always be correct url.
Do like this
<?php
$str = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
echo $str = array_shift(explode('&',$str));
Try this:
$current_link_path = substr($_SERVER['PHP_SELF'], 1);
$params = $_GET;
if ($params['message'] == 'success') {
unset($params['message']);
}
$current_link_redirect = $current_link_path . '?' . http_build_query($params);
Maybe not an answer, but a disclaimer for future visitors:
1) I would strongly recommend the function: http://pl1.php.net/parse_url.
And in that case:
$current_link = "$_SERVER[REQUEST_URI]";
$arguments = explode('&', parse_url($current_link, PHP_URL_QUERY));
print_r($arguments);
2) To build new url, use http://pl1.php.net/manual/en/function.http-build-url.php. This is the best, future modifications ready solution I think.
In that case this solution is a little overkill, but these functions are really great, and worth to introduce here.
Best regards

Adding a query string to a random URL

I want to add a query string to a URL, however, the URL format is unpredictable. The URL can be
http://example.com/page/ -> http://example.com/page/?myquery=string
http://example.com/page -> http://example.com/page?myquery=string
http://example.com?p=page -> http://example.com?p=page&myquery=string
These are the URLs I'm thinking of, but it's possible that there are other formats that I'm not aware of.
I'm wondering if there is a standard, library or a common way to do this. I'm using PHP.
Edit: I'm using Cbroe explanation and Passerby code. There is another function by Hamza but I guess it'd be better to use PHP functions and also have cleaner/shorter code.
function addQuery($url,array $query)
{
$cache=parse_url($url,PHP_URL_QUERY);
if(empty($cache)) return $url."?".http_build_query($query);
else return $url."&".http_build_query($query);
}
// test
$test=array("http://example.com/page/","http://example.com/page","http://example.com/?p=page");
print_r(array_map(function($v){
return addQuery($v,array("myquery"=>"string"));
},$test));
Live demo
I'm wondering if there is a standard, library or a common way to do this. I'm using PHP.
Depends on how failsafe – and thereby more complex – you want it to be.
The simplest way would be to look for whether there’s a ? in the URL – if so, append &myquery=string, else append ?myquery=string. This should cover most cases of standards-compliant URLs just fine.
If you want it more complex, you could take the URL apart using parse_url and then parse_str, then add the key myquery with value string to the array the second function returns – and then put it all back together again, using http_build_query for the new query string part.
Some spaghetti Code:
echo addToUrl('http://example.com/page/','myquery', 'string').'<br>';
echo addToUrl('http://example.com/page','myquery', 'string').'<br>';
echo addToUrl('http://example.com/page/wut/?aaa=2','myquery', 'string').'<br>';
echo addToUrl('http://example.com?p=page','myquery', 'string');
function addToUrl($url, $var, $val){
$array = parse_url($url);
if(isset($array['query'])){
parse_str($array['query'], $values);
}
$values[$var] = $val;
unset($array['query']);
$options = '';$c = count($values) - 1;
$i=0;
foreach($values as $k => $v){
if($i == $c){
$options .= $k.'='.$v;
}else{
$options .= $k.'='.$v.'&';
}
$i++;
}
$return = $array['scheme'].'://'.$array['host'].(isset($array['path']) ? $array['path']: '') . '?' . $options;
return $return;
}
Results:
http://example.com/page/?myquery=string
http://example.com/page?myquery=string
http://example.com/page/wut/?aaa=2&myquery=string
http://example.com?p=page&myquery=string
You should try the http_build_query() function, I think that's what you're looking for, and maybe a bit of parse_str(), too.

How can i run php code within array?

im using this php code (from a question on here):
<?php
define(TEMPLATES_LOCATION, 'templates/');
function TemplateFunction ($template, $replaces) {
$template = file_get_contents(TEMPLATES_LOCATION . $template);
if (is_array($replaces)) {
foreach($replaces as $replacekey => $replacevalue){
$template = str_replace('{$' . $replacekey . '}', $replacevalue, $template);
}
}
return $template;
}
$keys = array(
'TITLE' => 'This is page title',
'HEADER' => 'This is some header',
'GALLERY' => 'php while loop here'
);
echo TemplateFunction('body.tpl', $keys);
?>
The way my template file is set up is the following HTML:
<body>
<div id="gallery">{GALLERY}</div>
</body>
so where {GALLERY} is, the php script should replace that with my automatically generated <li><img src="images/'.$filename.'"/></li> which is being run in a while loop generated from a mysql request
what i thought might work is:
$keys = array(
'TITLE' => 'This is page title',
'HEADER' => 'This is some header',
'GALLERY' => 'while($row = mysql_fetch_array($result)){<li><img src="'.$row['filename'].'"/></li>})'
);
but it doesnt :(
Re your code:
$keys = array(
'TITLE' => 'This is page title',
'HEADER' => 'This is some header',
'GALLERY' => 'while($row = mysql_fetch_array($result)){<li><img src="'.$row['filename'].'"/></li>})'
);
I would consider it very poor practice to have PHP code embedded in your template data this way. Allow me to offer you a completely different solution...
Firstly, we need to encapsulate the code. The code you've shown above is trying to fetch data from a $result variable, but $result itself is obviously been set elsewhere. This isn't good, because if we ever want to change the way the gallery feature works, we would need to search all over the code to find different bits of it.
Instead, you should write the feature as a self-contained function (or a class if it's too complex for a single function), which would load the data, and process it.
Let's call that function loadGallery(). It might look something like this:
function loadGallery() {
$output = '';
$result = mysql_query('...gallery query here...');
while($row = mysql_fetch_array($result)) {
$output .= "<li><img src='{$row['filename']}'/></li>";
}
return '<ul>'.$output.'</ul>';
}
Obviously, it could be a lot more complex than that (eg you may want to paginate it, or offer category options; these would be written as parameters for the function). I've also not written any error checking, etc here for brevity.
Now that you've got that function, you can plug it into the template engine. You need to reference the function in your template.
You currently have template markers like this {TITLE}. In your code, these markers are swapped with plain text using str_replace(). That's fine. But in this case we now want to call a function instead, so we need to have a different kind of marker.
Let's write the gallery marker like this: {FUNCTION:loadGallery} instead of {GALLERY} as you currently have.
Now you can have an additional bit of code in your template engine that looks at these {function:} markers and replaces them with a function call. (You can keep the existing simple str_replace() method as well of course)
$funcReplaces = array( //similar to your existing $keys array, but for allowed functions
'loadGallery'
);
foreach($funcReplaces as $replaceFunc){
$template = str_replace('{function:' . $replaceFunc . '}', $replaceFunc(), $template);
}
This will run the function and put the output into the template.
So that answers the question for you.
What I should point out, however, is that there are a lot of other issues that you need to think about when writing a templating engine, from both a technical and security perspective. The above describes a basic way to resolve the specific question at hand, but it isn't a fantastic all-singing all-dancing template engine. It's still just a pretty basic one.
That's fine, if that's all you need, but if you expect this system to grow, it's worth noting that this whole area is that this is very much a problem that others have already solved, and solved well. There are several very good templating engines available for PHP. I would suggest that your best course of action would be to investigate some of them, and maybe use one of those instead of writing your own.
Some that you could try:
Smarty
Twig
Mustache
Hope that helps.
You cannot "execute PHP code within an array". You simply build the array programmatically:
while (/* something */) {
$keys['GALLERY'][] = $something;
}
I have found the following code that i've written to be the right solution to my issue:
$gallery = array();
while($row = mysql_fetch_assoc($result))
{
$gallery[] = '<li><img src="'.$row['gallery_image_filename'].'" width="'.$final_image_width.'" height="auto" style="margin: '.$other_margin.'px '.$gallery_image_margin.'px '.$other_margin.'px 0px"/></li>';
}
$gallery = implode(' ', $gallery);
i then can concatenate my $gallery variable into the 'GALLERY' => 'value' value and it outputs all the database results as required. Thanks to all for your help :)
Well, you can create an class with __toString magic method which will process all images on your gallery and then return the string.
class TemplateGallery{
private $images = array();
public function addImage($src){
$images[] = $src;
}
public function __toString(){
$str = "";
foreach($images as $image){
$str .= sprintf('<li><img src="%s"></li>',$image);
}
return $str;
}
}
Well, as the guy in comments said, it's too "hard", so, you can use an "pre-process" function, that will process your images array, and then return your template string.
$images = array(/* Put images src here */);
function processGallery($images){
$str = "";
foreach($images as $image){
$str .= sprintf('<li><img src="%s"></li>',$image);
}
return $str;
}
And then call that function on your array.

Categories