php eval string as function - php

What is the best way to go about defining a php function and the call to that function, in a string, and then executing that code i.e., eval? I'm trying to get the length of an encoded uri out of a function defined and called in a string.
$json_arr['my_function'] = "function hashfun1($enc_uri) { return strlen($enc_uri); } hashfun1($enc_uri);";
$hash_func = $json_arr['my_function'];
$hash_val = eval($hash_func);
print_r($hash_val); // should be length of encoded uri but displays "Parse error: syntax error, unexpected '%', expecting '&' or T_VARIABLE"
exit;
Thanks.

I guess you want:
$json_arr['my_function'] = "function hashfun1($enc_uri) { return strlen($enc_uri); } hashfun1('" . $enc_uri . '");";
You missed to populate $enc_uri.
Don't do this in production code, although it works. eval() is evil. You have been warned.

you need to escape "$" in double-quoted string. And check number of returns (second for eval):
$json_arr['my_function'] = "function hashfun1(\$enc_uri) { return strlen(\$enc_uri); } return hashfun1(\$enc_uri);";

I guess I need to use call_user_func(); This worked for me: $json_arr['my_function'] = function($enc_uri) { return strlen($enc_uri); };
$hash_val = call_user_func($json_arr['my_function'], $enc_uri);
print_r($hash_val);
exit;
Thanks for the help guys.

Related

Why am I not able to use a number in php public function class at starting?

So I'm trying to create a page, and the software I use, uses the below code to create pages:
public function 2testnew()
{
$pagetitle = "testnew";
$this->SetVars(compact('pagetitle'));
return $this->render(dirname(__DIR__) . "/" . self::_VIEWS_PATH . "/" . self::_PAGES_DIR, __FUNCTION__, TEMPLATE_NAME);
}
Unfortunately, when I start my page name with "2" at the beginning of the page name, my website stops working, and also on Notepad++, it shows "2" in orange color, meaning there's something wrong.
I'm a beginner at PHP, so please guide me. How do I achieve a class starting with a number instead because I want to create a page that has a number at the beginning of the name?
Thank you for your help.
There's something incomplete in your error reporting settings. When properly configured you'd get something like:
Parse error: syntax error, unexpected '2' (T_LNUMBER)
Why doesn't PHP parser expect a 2 character there? Because it isn't a valid class method name. It's admittedly not documented where you'd expect it to but it can be found in the functions chapter (class methods follow the same rules as regular functions):
Function names follow the same rules as other labels in PHP. A valid function name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: ^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$.
If you absolutely need to, how can you? You can hack it with e.g. magic methods:
class MyController
{
private function twotestnew($one, $two)
{
echo 'Calling ', __METHOD__, '() with arguments ', $one, ' and ', $two, "\n";
}
public function __call($name, $arguments)
{
$map = [
'2testnew' => 'twotestnew',
];
$name = mb_strtolower($name);
if (isset($map[$name])) {
return call_user_func_array([$this, $map[$name]], $arguments);
}
throw new RuntimeException('Not found');
}
}
This could use many refinements but I hope you get the idea. You can test the above code with the variable functions syntax (for good or bad, the syntax doesn't apply to function definitions):
$page = new MyController();
$page->{'2testnew'}('Foo', 'Bar');
It seems like your function name is invalid. Function names in php cannot start with a number. You can read more here.

PHP eval not executing properly

Could someone point out what I'm mistaking here? :)
<?php
$q = $_GET[q];
$acuman = <<<PARSE
input: (contains: "hello"){
output: "hello";
}
PARSE;
$acuman = str_replace("input: (contains: ", 'if(strpos(', $acuman);
$acuman = str_replace("){", ', $q) !== false) {', $acuman);
$acuman = str_replace("output: ", '$output = ', $acuman);
eval($acuman);
?>
I'm attempting to execute the string $acuman, a heredoc which has been altered by various str_replace functions. However, it is not doing what I intend it to do, and I am confused as of what to do as I've tried many different things.
Since many people seemed confused: My intention is for the code in the string $acuman to be executed as code properly. I just want the eval function to work. I know that eval is evil, please, stop: I'm just asking for help for solving the problem at hand.
Edit: When I echo the string $acuman, this is what I get:
if(strpos("hello", $q) !== false) { $output = "hello"; }
You have the arguments in the wrong order:
if(strpos($q, "hello") !== false) { $output = "hello"; }
strpos() takes the "haystack" (string being searched) as the first argument and the "needle" (string to find as within the "haystack") as the second argument.
Ok, so... $acuman appears to contain the following:
if(strpos("hello", $q) !== false) {
echo "hello";
}
Which indicates that $q needs to contain a portion of "hello" to echo the string "hello".
I don't see any problem here, EXCEPT that $q = $_GET[q]; won't work with any modern version because q is treated like a constant, not a variable nor a string literal array index. See this PHP documentation on the subject.
Upon changing to $q = $_GET['q']; instead (note the quotes), it seems like this code actually works. It will output "hello" whenever passing any portion of "hello" to the URL parameter (which gets passed to the PHP code).
Needless to say: Do not use this code for production. The code as it is is very vulnerable and allows a user to pass raw PHP code through to your script to execute. The function of this code can be completely re-written in a much safer manner, but you have expressed the desire to continue using eval(); so please be careful.
Enjoy.

Where is my unexpected T_STRING?

Ordinarily, one would expect that the unexpected T_STRING implies a missing semicolon. However, in this case, where's the semicolon missing from??
global $lay;
$yal = eval("return '$lay';");
echo $yal . "\n";
The error is thrown in the eval, viz
Parse error: syntax error, unexpected T_STRING in ... BOGARIP.php(140) : eval()'d code on line 1
with $lay containing
$reportDate\t$heads['Account']\t$id\t$heads['Time zone']\t$heads['Campaign']\t$heads['Ad group']\t$heads['Network']\t$heads['Network (with search partners)']\t\t$heads['Ad group state']\t$heads['Campaign state']\t$heads['Impressions']\t$heads['Clicks']\t$heads['CTR']\t$heads['Avg. CPC']\t$heads['Avg. CPM']\t$heads['Cost']\t$heads['Avg. position']
Does this imply that the bug is actually in $lay or am I missing something else? Is this level of string substitution even possible?
You really shouldn't be doing anything with eval, generally speaking. But, for the sake of the technical issue here, consider the following:
eval("return '$lay';");
You're surrounding the $lay variable with single quotes. Now let's look at the contents of this variable:
$reportDate\t$heads['Account...
See the problem? You're using single quotes within the value too. Swap out the quotes in your eval statement so there is no longer a conflict:
eval('return "$lay";');
Again again, please don't use this code. By and large, professionals will steer you away from every using eval, as it opens up your application to a great deal of potential woes. Please find another way to do whatever it is you're attempting.
Took #Evert's advice and refactored. Now the format contains
%DATE%\t%Account%\t%ID%\t%Time zone%\t%Campaign%\t%Ad group%\t%Network%\t%Network (with search partners)%\t\t%Ad group state%\t%Campaign state%\t%Impressions%\t%Clicks%\t%CTR%\t%Avg. CPC%\t%Avg. CPM%\t%Cost%\t%Avg. position%
and the code
$heads["ID"] = $id;
$heads["DATE"] = $reportDate;
...
global $lay;
$layout = $lay;
foreach ($heads as $key => $value) {
$layout = str_replace("%" . $key . "%", $value, $layout);
}
$layout = str_replace("\\n", "\n", $layout);
$layout = str_replace("\\t", "\t", $layout);

PHP string in a function name

How to put PHP string in a function name?
for ($i=1;$i<10;$i++) {
function my_function_$i() {
//Parse error: syntax error, unexpected T_VARIABLE, expecting '('
include($i.'.php');
}
}
UPDATE:
OK. closed this question, I shall study for more.
there is something utterly wrong with your architecture if you come to a question like this.
it seems you do not understand what functions are for.
there should be no functions like my_function_$i() but one function my_function($i)
There should be no enumerated includes as well. What are these php files for?
Check this out - maybe what you're looking for
http://php.net/manual/en/function.create-function.php
from that page:
<?php
$newfunc = create_function('$a,$b', 'return "ln($a) + ln($b) = " . log($a * $b);');
echo "New anonymous function: $newfunc\n";
echo $newfunc(2, M_E) . "\n";
// outputs
// New anonymous function: lambda_1
// ln(2) + ln(2.718281828459) = 1.6931471805599
?>
Firstly, this is a horrible thing to do. Consider using closures, or create_function(), or passing $i as an argument.
Secondly - the only way I can think of to do this (but for Christ's sake, don't) is with eval():
for ($i = 1; $i < 10; $i++) {
eval("function my_function_$i() {
include('$i.php');
}");
}
Maybe you can use eval for do like this:
for ($i=1;$i<10;$i++) {
eval('function myfunc_'.$i.'(){echo '.$i.';}');
}
myfunc_5();
//Output
//5

Proper syntax for substituting in php?

Beginner question.
How do I substitute:
$_SESSION['personID'] for {personID} in the following:
public static $people_address = "/v1/People/{personID}/Addresses"
look this:
$template = "/v1/People/{personID}/Addresses";
$people_address = str_replace('{personID}', $_SESSION['personID'], $template);
echo $people_address;
output:
/v1/People/someID/Addresses
EDIT: This answer no longer applies to the question after edit but I'm leaving it around for a little while to explain some questions that occured in comments another answer to this question
There are a few ways - the . operator is probably the easiest to understand, its entire purpose is to concatenate strings.
public static $people_address = "/v1/People/".$_SESSION['personID']."/Addresses";
//PHP Parse error: syntax error, unexpected '.', expecting ',' or ';'
public static $people_address = "/v1/People/$_SESSION[personID]/Addresses";
//PHP Parse error: syntax error, unexpected '"' in
However you can't use concatenation in property declarations sadly - just simple assignment. You cant use the "string replacement" format either:
To work around it you could assign the static outside of the class - i.e.:
class test {
public static $people_address;
// ....
}
// to illustrate how to work around the parse errors - and show the curly braces format
test::$people_address = "/v1/People/${_SESSION[personID]}/Addresses";
// another (much better) option:
class test2 {
public static $people_address;
public static function setup() {
self::$people_address = "/v1/People/".$_SESSION['personID']."/Addresses";
}
}
// somewhere later:
test2::setup();

Categories