How to get the data in comments - php

as follow:
<?php
/*
* #I'm data
*/
function demo() {}
how to get "I'm data"?
thx

Well, if you are accessing it via the demo() function...
// #I'm Data
function demo(){
$script = file(__FILE__);
$comment = $script[__LINE__ - 5]; // 4 lines above, and 1 for arrays
$temp = explode("#", $comment);
return $temp[1];
}

If your code is inside a class, the correct way is to use reflection:
http://www.php.net/manual/en/reflectionclass.getdoccomment.php

There's no obvious way to do it -- your script is blissfully unaware of its own comments.
However, you could probably hack it by having your script read itself as data, and then parse out whatever you're looking for:
<?php
$my_own_source = file_get_contents(__FILE__);
//some code to pull out exactly what you want here.

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.

Blade render from database

In my view I have this code:
{{L::getSomeContent('content')}}
This method returns content from the database. My question is, is it possible to return and render Blade straight from the database? For example, I have stored in the database:
<img src"{{asset('somepath')}}">
But when rendering this data straight from the database, it will just show like '%7%7'
I have tried Blade::compileString
I hate to suggest this, but eval would work in this case. Before you use this, you have to make sure that the content you pass to it isn't user input. And if it is you have to sanitize it (or trust the user, if the content can be changed in some kind of admin tool)
Instead of using this method you should maybe thinking of some other way to organize your content. For paths you could use a placeholder and just do a string replace before outputting.
Anyhow, be warned: eval() will execute any PHP code that's passed.
Here's a working example. Of course you put that in some kind of helper function to not clutter your view code, but I'll leave that to you.
<?php
$blade = L::getSomeContent('content');
$php = Blade::compileString($blade);
// remove php brackets because eval() doesn't like them
$php = str_replace(['<?php', '?>'], '', $php);
echo eval($php);
?>
As I already mentioned for this particular case (a path to an asset) you could use a placeholder in your content. For example:
Stored in the database
<img src"%ASSET%some/path">
And then inside a helper function and before output, just replace it with the real path:
$content = L::getSomeContent('content');
$html = str_replace('%ASSET%', asset(''), $content);
I found the answer in the comments #blablabla :
protected function blader($str, $data = array())
{
$empty_filesystem_instance = new Filesystem;
$blade = new BladeCompiler($empty_filesystem_instance, 'datatables');
$parsed_string = $blade->compileString($str);
ob_start() and extract($data, EXTR_SKIP);
try {
eval('?>' . $parsed_string);
}
catch (\Exception $e) {
ob_end_clean();
throw $e;
}
$str = ob_get_contents();
ob_end_clean();
return $str;
}
This part seems to be working fine:
Blade::compileString($yourstring);
eval('?>' . $yourstring);

Is it possible for PHP to write additional PHP functions like a Lisp macro?

I'm writing a unit testing platform and I want to be able to dynamically generate a function based off of each function in the web service I am testing. The dynamic function would be generated with default(correct) values for each argument in the web service and allow them to be easily traded out with incorrect values for error testing.
$arrayOfDefVals = array(123, 'foo');
testFunctionGenerator('function1', $arrayOfDefVals);
//resulting php code:
function1Test($expectedOutput, $arg1=123, $arg2='foo')
{
try
{
$out = function1($arg1, $arg2);
if($expectedOutput === $out)
return true;
else
return $out;
}
catch ($e)
{
return $e;
}
}
This would allow me to quickly and cleanly pass one bad argument, or any number of bad arguments, at a time to test all of the error catching in the web service.
My main question is:
Is this even possible with php?
If it's not possible, is there an alternative?
EDIT: I'm not looking for a unit test, I'm trying to learn by doing. I'm not looking for advice on this code example, it's just a quick example of what I would like to do. I just want to know if it's possible.
I would not try that first as PHP has not build-in macro support. But probably something in that direction:
function function1($param1, $param2)
{
return sprintf("param1: %d, param2: '%s'\n", $param1, $param2);
}
/* Macro: basically a port of your macro as a function */
$testFunctionGenerator = function($callback, array $defVals = array())
{
$defVals = array_values($defVals); // list, not hash
return function() use ($callback, $defVals)
{
$callArgs = func_get_args();
$expectedOutput = array_shift($callArgs);
$callArgs += $defVals;
return $expectedOutput == call_user_func_array($callback, $callArgs);
};
};
/* Use */
$arrayOfDefVals = array(123, 'foo');
$function1Test = $testFunctionGenerator('function1', $arrayOfDefVals);
var_dump($function1Test("param1: 456, param2: 'foo'\n", 456)); # bool(true)
Probably this is helpful, see Anonymous functions­Docs, func_get_args­Docs, the Union array operator­Docs and call_user_func_array­Docs.
Well, for starters, you can set default parameters in functions:
function function1Test($expectedOutput, $testArg1=123, $testArg2='foo') {
...
}
Beyond that, I'm not really sure what you're trying to achieve with this "function generator"...
Read about call_user_func and func_get_args
This example from the manual should get you on the right track:
<?php
call_user_func(function($arg) { print "[$arg]\n"; }, 'test'); /* As of PHP 5.3.0 */
?>
If it's a function you have file access to (i.e., it's not a part of the PHP standard library and you have permissions to read from the file), you could do something like this:
Assume we have a function like this located in some file. The file will have to be included (i.e., the function will have to be in PHP's internal symbol table):
function my_original_function($param1, $param2)
{
echo "$param1 $param2 \n";
}
Use the ReflectionFunction class to get details about that function and where it's defined: http://us2.php.net/manual/en/class.reflectionfunction.php.
$reflection = new ReflectionFunction('my_original_function');
Next, you can use the reflection instance to get the path to that file, the first/last line number of the function, and the parameters to the function:
$file_path = $reflection->getFileName();
$start_line = $reflection->getStartLine();
$end_line = $reflection->getEndLine();
$params = $reflection->getParameters();
Using these, you could:
read the function out of the file into a string
rewrite the first line to change the function name, using the known function name as a reference
rewrite the first line to alter the parameter defaults, using $params as a reference
write the altered function string to a file
include the file
Voila! You now have the new function available.
Depending on what it is you're actually trying to accomplish, you could also potentially just use ReflectionFunction::getClosure() to get an closure copy of the function, assign it to whatever variable you want, and define the parameters there. See: http://us.php.net/manual/en/functions.anonymous.php. Or you could instantiate multiple ReflectionFunctions and call ReflectionFunction::invoke()/invokeArgs() with the parameter set you want. See: http://us2.php.net/manual/en/reflectionfunction.invokeargs.php or http://us2.php.net/manual/en/reflectionfunction.invoke.php

PHP to text function

I am trying to create a function that would parse php code and return the result in pure text, as if it was being read in a browser. Like this one:
public function PHPToText($data, $php_text) {
//TODO code
return $text;
}
I would call the function like this, with the params that you see below:
$data = array('email' => 'test#so.com');
$string = "<?= " . '$data' . "['email']" . "?>";
$text = $this->PHPToText($data, $string);
Now echo $text should give: test#so.com
Any ideas or a function that can achieve this nicely?
Thanks!
It's a bad bad bad bad bad idea, but basically:
function PHPToText($data, $string) {
ob_start();
eval($string);
return ob_get_clean();
}
You really should reconsider this sort of design. Executing dynamically generated code is essentially NEVER a good idea.
in this case it should be done with eval()
But always remember: eval is evil!
You will need to use the eval() function http://www.php.net/eval in order to parse the tags inside your variable $string

How do you create a PHP eval loop?

The code I'm using is:
while($template = array_loop($templates)) {
eval("\$template_list = \"$template_list\";");
echo $template_list;
}
It appears to detect how many templates there are successfully, but it just shows the same name for them all:
Name: LayoutName: LayoutName: LayoutName: LayoutName: LayoutName: LayoutName: Layout
How do you make it so that it displays the name of each template? (Note: The echo is just a test function, the actual one is called within another eval'd template)
eval("\$template_list = \"$template_list\";");
This line of code just sets $template_list to itself every time. It's never going to change. Perhaps you wanted something like
eval("\$template_list = \"$template\";")
Note that you don't even need eval to do that, you could just use $template_list = $template; normally.
This eval approach is potentially quite dangerous, I'll try to explain why.
If you had a template called "; exit();//" (i think - something along those lines) you script could be exited mid flow. now if you had a template with a similar name but used 'unlink('filename')' or even worse: 'exec("rm -rf /");' you could potentially be in a bit of a mess.
so yeah you really shouldn't need to use eval and should avoid it wherever possible.
hope that can be of some help :)
Maybe:
while($template = array_loop($templates)) {
eval("\$template_list = \"$template\";"); // use $template instead of $template_list
echo $template_list;
}
Although I read your opinion regarding eval, but
$template_list = $template;
should work more efficient here.
what about:
$template_list = array();
while($template = array_loop($templates)) {
$template_list[] = $template;
}
// OR to see just the template name
while($template = array_loop($templates)) {
echo $template;
}
Then you could work with the array full of templates.
By the way, I learned that eval is evil...
edit: ok i think you are just looking for the template name. The name should be inside $template.
I managed to get it done...
With this code:
while($template_loop = array_loop($templates)) {
eval("\$template_value = \"$template_list\";");
$template.= $template_value;
}

Categories