How to display string from function call inside concatenation? - php

I need to join/concatenate strings from a return of a function call, and from a variable without using the traditional concatenation ..
In this scenario, it should be displaying a url string.
Below is my actual code.
CODE:
$test = "{ config('app.url') }/{ $username }";
die(print_r($test));
Current Result:
{ config('app.url') }/testuser
Expected Result:
http://localhost:8000/testuser

You may read more about complex (curly) syntax in a quoted string, however you may achieve what you want with that code:
$test = "{${config('app.url')}}/{$username}";
die(print_r($test));
But I personally prefer:
$appUrl = config('app.url');
$test = "{$appUrl}/{$username}";
die(print_r($test));
Does that work for you?

It's not possible. You can only parse variables inside string. The only way is assigning function result to variable:
$url = config('app.url');
$test = "{$url}/{$username}";
You can read more about Variable parsing in strings

You can try the following way
<?php
$_ = function ( $v ) { return $v; };
function config($url)
{
return $url;
}
$username = 'u_name';
echo "{$_( config('app.url') )}/{$username}";

Related

PHP convert string into object sub sub variable

I have the following a PHP object with the following properties:
Object:
-Advanced
--Data
To access it in PHP I would have to do the following:
$object->Advanced->Data
Now I want to define a string which has a syntax like this:
$string = "Advanced->Data";
How do I proceed from here to be able to use:
$object->$string = "Something";
So that in the end
$object->Advanced->Data = "Something";
I couldn't figure out using eval or $object->{$string}
If I try to use $object->$string
PHP creates a new property called "Advanced->Data", basically not interpreting the -> Operator.
Though it is a hack, try this, it should work for your case
$arr = array();
$arr['Advanced']['Data'] = 'something';
$string = json_decode(json_encode($arr), 0);
echo $string->Advanced->Data;
Though it is a hack, this can also fetch your desire
$string = &$object->Advanced->Data;
$string = "here we go";
var_dump($object->Advanced->Data);
Probably eval() is not best solution, but it can be useful in your case:
class obj2 {
public $Data = 'test string';
}
class obj1 {
public $Advanced;
public function __construct() {
$this->Advanced = new obj2();
}
}
$test = new obj1();
$string1 = "\$test->Advanced->Data = 'new string';";
$string2 = "\$result = \$test->Advanced->Data;";
eval($string1);
eval($string2);
echo $result . PHP_EOL;
Output will be "new string".
Once try this,
$string = "Advanced->Data";
$arr = explode("->",$string);
$temp = $object->{$arr[0]}->$arr[1];
But this is specific condition. Let me know your requirement if this is not the answer.

PHP: Access nested property from variable [duplicate]

Is it possible to create a variable variable pointing to an array or to nested objects? The php docs specifically say you cannot point to SuperGlobals but its unclear (to me at least) if this applies to arrays in general.
Here is my try at the array var var.
// Array Example
$arrayTest = array('value0', 'value1');
${arrayVarTest} = 'arrayTest[1]';
// This returns the correct 'value1'
echo $arrayTest[1];
// This returns null
echo ${$arrayVarTest};
Here is some simple code to show what I mean by object var var.
${OBJVarVar} = 'classObj->obj';
// This should return the values of $classObj->obj but it will return null
var_dump(${$OBJVarVar});
Am I missing something obvious here?
Array element approach:
Extract array name from the string and store it in $arrayName.
Extract array index from the string and store it in $arrayIndex.
Parse them correctly instead of as a whole.
The code:
$arrayTest = array('value0', 'value1');
$variableArrayElement = 'arrayTest[1]';
$arrayName = substr($variableArrayElement,0,strpos($variableArrayElement,'['));
$arrayIndex = preg_replace('/[^\d\s]/', '',$variableArrayElement);
// This returns the correct 'value1'
echo ${$arrayName}[$arrayIndex];
Object properties approach:
Explode the string containing the class and property you want to access by its delimiter (->).
Assign those two variables to $class and $property.
Parse them separately instead of as a whole on var_dump()
The code:
$variableObjectProperty = "classObj->obj";
list($class,$property) = explode("->",$variableObjectProperty);
// This now return the values of $classObj->obj
var_dump(${$class}->{$property});
It works!
Use = & to assign by reference:
$arrayTest = array('value0', 'value1');
$arrayVarTest = &$arrayTest[1];
$arrayTest[1] = 'newvalue1'; // to test if it's really passed by reference
print $arrayVarTest;
In echo $arrayTest[1]; the vars name is $arrayTest with an array index of 1, and not $arrayTest[1]. The brackets are PHP "keywords". Same with the method notation and the -> operator. So you'll need to split up.
// bla[1]
$arr = 'bla';
$idx = 1;
echo $arr[$idx];
// foo->bar
$obj = 'foo';
$method = 'bar';
echo $obj->$method;
What you want to do sounds more like evaluating PHP code (eval()). But remember: eval is evil. ;-)
Nope you can't do that. You can only do that with variable, object and function names.
Example:
$objvar = 'classObj';
var_dump(${$OBJVarVar}->var);
Alternatives can be via eval() or by doing pre-processing.
$arrayTest = array('value0', 'value1');
$arrayVarTest = 'arrayTest[1]';
echo eval('return $'.$arrayVarTest.';');
eval('echo $'.$arrayVarTest.';');
That is if you're very sure of what's going to be the input.
By pre-processing:
function varvar($str){
if(strpos($str,'->') !== false){
$parts = explode('->',$str);
global ${$parts[0]};
return $parts[0]->$parts[1];
}elseif(strpos($str,'[') !== false && strpos($str,']') !== false){
$parts = explode('[',$str);
global ${$parts[0]};
$parts[1] = substr($parts[1],0,strlen($parts[1])-1);
return ${$parts[0]}[$parts[1]];
}else{
return false;
}
}
$arrayTest = array('value0', 'value1');
$test = 'arrayTest[1]';
echo varvar($test);
there is a dynamic approach for to many nested levels:
$attrs = ['level1', 'levelt', 'level3',...];
$finalAttr = $myObject;
foreach ($attrs as $attr) {
$finalAttr = $finalAttr->$attr;
}
return $finalAttr;

Convert String to variable in PHP inside function argument

below is the code I have created. My point here is to convert all strings inside the function argument.
For example, fname('variable1=value1&variable2=value2'); I need to convert variable1 & variable2 into ang variable as $variable1, $variable2 instead parsing a plain text. I found out eval() function is useful but it only takes one string which is the "variable1" and its value.
function addFunction($arg){
echo eval('return $'. $arg . ';');
}
addFunction('variable1=value1&variable2=value2');
Now the problem is I got this error "Parse error: syntax error, unexpected '=' in D:\xampp\htdocs...\index.php(7) : eval()'d code on line 1". But if I have only one variable and value inside the function argument it works perfect, but I need to have more parameters here. Is this possible to do this thing or is there any other way to count the parameters before it can be evaluated?
Thank you,
function addFunction($arg)
{
parse_str($arg, $args);
foreach ($args as $key => $val) {
echo $key , " --> " , $val, "\n";
}
}
addFunction('variable1=value1&variable2=value2');
Output
variable1 --> value1
variable2 --> value2
You can also use
function addFunction($arg)
{
parse_str($arg);
echo $variable2; // value2
}
addFunction('variable1=value1&variable2=value2');
You are trying to create a variable with this name:
$variable1=value1&variable2=value2
You need to explode it at the & to get just the desired future variable names.
function addFunction($arg){
echo eval('return $'. $arg . ';');
}
$string = 'variable1=value1&variable2=value2';
$array = explode('&', $string);
foreach($array as $part)
{
addFunction($part);
}
You can break a string up using the PHP explode function, and then use eval to evaluate each variable indepedently.
$myvars = explode ('$', 'variable1=value1&variable2=value2');
$myvars is then an array which you can parse and feed to eval as needed.
Perhaps you can use explode()?
$varArr = explode("&",$arg);
foreach ($varArr as $varKey=>$varVal) {
echo eval('return $'.$varKey.'='.$varVal.';');
}
You need split the $arg at & to get each variable and then again at = to get each variable and value.
$arg = 'variable1=value1&variable2=value2';
$vars = explode('&', $arg);
foreach ($vars as $var) {
$parts = explode("=", $var);
echo eval('return $'. $parts[0] . '='. $parts[1] . ';');
}
Something like this:
function addFunction($arg)
{
$varArr = explode("&",$arg);
$varResponse ="";
foreach ($varArr as $varKey=>$varVal) {
$varResponse = $varResponse."$".$varVal.";";
}
return $varResponse;
}
echo addFunction('variable1=value1&variable2=value2');
Saludos ;)

How to pass parameter with preg_replace() with 'e' modifier?

I have a question about preg_replace() function. I'm using it with 'e' modifier. Here is code snippet:
$batchId = 2345;
$code = preg_replace("/[A-Za-z]{2,4}[\d\_]{1,5}[\.YRCc]{0,4}[\#\&\#\^]{0,2}/e",
'translate_indicator(\'$0\', {$batchId})', $code);
I want to have access to $batchId variable inside translate_indicator($code, $batch=false) function. The above exapmle, unfortunately, doesn't work correctly: $batch is invisible(var_dump() result is bool(false)) within translate_indicator().
Probably, I have syntax mistakes in replacement code. Or, maybe, it's impossible to pass variables with preg_replace()?
Update for the first two answers.
Thank you for answers, but your advice didn't help. Besides I've already tried double qoutes instead of single qoutes. I've just simplified code to test possibility of passing parameter to the function:
$code = preg_replace("/[A-Za-z]{2,4}[\d\_]{1,5}[\.YRCc]{0,4}[\#\&\#\^]{0,2}/e",
"translate_indicator('$0', 12)", $code);
Also I've removed default value for the $batch within translate_indicator(). Result:
Warning: Missing argument 2 for translate_indicator()
So I think it's impossible to pass parameter using this approach.:(
$batchId = 2345;
$code = 'AA1#';
$code = preg_replace(
"/[A-Za-z]{2,4}[\d\_]{1,5}[\.YRCc]{0,4}[\#\&\#\^]{0,2}/e",
"translate_indicator('\$0', $batchId)", /* if $batchId can be a string use 'batchId' */
$code);
function translate_indicator($s, $batchId) {
echo "translate_indicator($s, $batchId) invoked\n";
}
prints translate_indicator(AA1#, 2345) invoked.
You can also use preg_replace_callback and a class/an object
class Foo {
public $batchId = 2345;
public function translate_indicator($m) {
echo "batchId=$this->batchId . $m[0]\n";
}
}
$code = 'AA1#';
$foo = new Foo;
$code = preg_replace_callback(
'/[A-Za-z]{2,4}[\d\_]{1,5}[\.YRCc]{0,4}[\#\&\#\^]{0,2}/',
array($foo, 'translate_indicator'),
$code
);
As of php 5.3. you can also use an anonymous function + closure to "pass" the additional parameter.
$code = 'AA1#';
$batchId = 2345;
$code = preg_replace_callback(
'/[A-Za-z]{2,4}[\d\_]{1,5}[\.YRCc]{0,4}[\#\&\#\^]{0,2}/',
function($m) use ($batchId) {
echo "batchid=$batchId . code=$m[0]\n";
},
$code
);
try this instead
$batchId = 2345;
$code = preg_replace("/[A-Za-z]{2,4}[\d\_]{1,5}[\.YRCc]{0,4}[\#\&\#\^]{0,2}/e",
"translate_indicator('$0', {$batchId})", $code);
singly-quoted strings aren't expanded (i.e. $batchId won't be subsituted).
Use "translate_indicator('\$0', $batchId)" instead of 'translate_indicator(\'$0\', {$batchId})'.

trim url(query string)

I have a query string like the one given below:
http://localhost/project/viewMember.php?sort=Y2xhc3M=&class=Mw==&page=9
Now variable: page in query string can be anywhere within the query string either in beginning or middle or at end (like ?page=9 or &page=9& or &page=9).
Now, I need to remove page=9 from my query string and get a valid query string.
Lots of ways this could be done, including regex (as seen below). This is the most robust method I can think of, although it is more complex than the other methods.
Use parse_url to get the query string from the url (or write your own function).
Use parse_str to convert the query string into an array
unset the key that you don't want
Use http_build_query to reassemble the array into a query string
Then reconstruct the Url (if required)
Try:
preg_replace('/page=\d+/', '', $url);
Tried writing a function for this. Seems to work:
<?php
$url = "http://localhost/project/viewMember.php?sort=Y2xhc3M=&class=Mw==&page=9";
// prints http://localhost/project/viewMember.php?sort=Y2xhc3M=&class=Mw==
print changeURL($url) . "\n";
$url = "http://localhost/project/viewMember.php?sort=Y2xhc3M=&page=9&class=Mw==";
// prints http://localhost/project/viewMember.php?sort=Y2xhc3M=&class=Mw==
print changeURL($url) . "\n";
function changeURL($url)
{
$arr = parse_url($url);
$query = $arr['query'];
$pieces = explode('&',$query);
for($i=0;$i<count($pieces);$i++)
{
if(preg_match('/^page=\d+/',$pieces[$i]))
unset($pieces[$i]);
}
$query = implode('&',$pieces);
return "$arr[scheme]://$arr[host]$arr[user]$arr[pass]$arr[path]?$query$arr[fragment]";
}
?>
I created these two functions:
function cleanQuery($queryLabels){
// Filter all items in $_GET which are not in $queryLabels
if(!is_array($queryLabels)) return;
foreach($_GET as $queryLabel => $queryValue)
if(!in_array($queryLabel, $queryLabels) || ($queryValue == ''))
unset($_GET[$queryLabel]);
ksort($_GET);
}
function amendQuery($queryItems = array()){
$queryItems = array_merge($_GET, $queryItems);
ksort($queryItems);
return http_build_query($queryItems);
}
To remove the page part I would use
$_GET = amendQuery(array('page'=>null));
cleanQuery does the opposite. Pass in an array of the terms you want to keep.
function remove_part_of_qs($removeMe)
{
$qs = array();
foreach($_GET as $key => $value)
{
if($key != $removeMe)
{
$qs[$key] = $value;
}
}
return "?" . http_build_query($qs);
}
echo remove_part_of_qs("page");
This should do it, this is my first post on StackOverflow, so go easy!

Categories