Detect all PHP functions also with line break - php

I have a script with a regex, which detect all defined internal functions in php. The script is working well, but there is a problem with the linebreaks.
With this script I searching for internal and defined funtions from PHP. Every function have to be replaced with the new function "no_function()".
$functions=get_defined_functions();
for($i=0;$i<count($functions["internal"]);$i++){
//Include array functions
if($functions["internal"][$i]=="array"||$functions["internal"][$i]=="array_push"){
}else{
$code=preg_replace('#('.$functions["internal"][$i].'[ |\n|\r|\t]*\([ |\n|\r|\t]*.*\))#i',"no_function()",$code);
}
}
When I had a function like:
str_replace($search,$replace,$string);
The function will not called because it will replace with no_function();
It will work normally. But if I have a function like that:
str_replace($search,
$replace,
$string);
The regex don't detect that, but PHP will execute that as well. I am a noob with regex. Can someone help me?
Thanks for every response.

Not sure about your use case. But you could use namespaces and redeclare internal functions under your namespace for a quick hack that will replace internal functions with no return.
First make a file consisting of dummy internal functions.
<?php
$funcs = get_defined_functions();
$output = "<?php\n";
$output .= "namespace example;";
foreach ($funcs['internal'] as $func_name) {
$output.= "function $func_name () {}\n";
}
file_put_contents('dummy_funcs.php', $output);
Then in another file (perhaps a common bootstrap) include your dummy functions early.
<?php
namespace example;
include 'dummy_funcs.php';
echo str_replace('w', 'l', 'bawls');
Outputs nothing.
The upshot here is that you don't need to edit your code (other than adding the include). It could however be a pain depending on your existing namespacing.

Related

How to write a loop while inside heredoc [duplicate]

In PHP, the HEREDOC string declarations are really useful for outputting a block of html. You can have it parse in variables just by prefixing them with $, but for more complicated syntax (like $var[2][3]), you have to put your expression inside {} braces.
In PHP 5, it is possible to actually make function calls within {} braces inside a HEREDOC string, but you have to go through a bit of work. The function name itself has to be stored in a variable, and you have to call it like it is a dynamically-named function. For example:
$fn = 'testfunction';
function testfunction() { return 'ok'; }
$string = <<< heredoc
plain text and now a function: {$fn()}
heredoc;
As you can see, this is a bit more messy than just:
$string = <<< heredoc
plain text and now a function: {testfunction()}
heredoc;
There are other ways besides the first code example, such as breaking out of the HEREDOC to call the function, or reversing the issue and doing something like:
?>
<!-- directly output html and only breaking into php for the function -->
plain text and now a function: <?PHP print testfunction(); ?>
The latter has the disadvantage that the output is directly put into the output stream (unless I'm using output buffering), which might not be what I want.
So, the essence of my question is: is there a more elegant way to approach this?
Edit based on responses: It certainly does seem like some kind of template engine would make my life much easier, but it would require me basically invert my usual PHP style. Not that that's a bad thing, but it explains my inertia.. I'm up for figuring out ways to make life easier though, so I'm looking into templates now.
If you really want to do this but a bit simpler than using a class you can use:
function fn($data) {
return $data;
}
$fn = 'fn';
$my_string = <<<EOT
Number of seconds since the Unix Epoch: {$fn(time())}
EOT;
I would not use HEREDOC at all for this, personally. It just doesn't make for a good "template building" system. All your HTML is locked down in a string which has several disadvantages
No option for WYSIWYG
No code completion for HTML from IDEs
Output (HTML) locked to logic files
You end up having to use hacks like what you're trying to do now to achieve more complex templating, such as looping
Get a basic template engine, or just use PHP with includes - it's why the language has the <?php and ?> delimiters.
template_file.php
<html>
<head>
<title><?php echo $page_title; ?></title>
</head>
<body>
<?php echo getPageContent(); ?>
</body>
index.php
<?php
$page_title = "This is a simple demo";
function getPageContent() {
return '<p>Hello World!</p>';
}
include('template_file.php');
I would do the following:
$string = <<< heredoc
plain text and now a function: %s
heredoc;
$string = sprintf($string, testfunction());
Not sure if you'd consider this to be more elegant ...
For completeness, you can also use the !${''} black magic parser hack:
echo <<<EOT
One month ago was { ${!${''} = date('Y-m-d H:i:s', strtotime('-1 month'))} }.
EOT;
See it live on 3v4l.org.
Note: PHP 8.2 deprecated bare ${} variable variables within strings, in preference to the explicit { ${} } syntax. The example above uses this explicit format to remove the deprecation notice, though it makes this method even more noisy!
Try this (either as a global variable, or instantiated when you need it):
<?php
class Fn {
public function __call($name, $args) {
if (function_exists($name)) {
return call_user_func_array($name, $args);
}
}
}
$fn = new Fn();
?>
Now any function call goes through the $fn instance. So the existing function testfunction() can be called in a heredoc with {$fn->testfunction()}
Basically we are wrapping all functions into a class instance, and using PHP's __call magic method to map the class method to the actual function needing to be called.
I'm a bit late, but I randomly came across it. For any future readers, here's what I would probably do:
I would just use an output buffer. So basically, you start the buffering using ob_start(), then include your "template file" with any functions, variables, etc. inside of it, get the contents of the buffer and write them to a string, and then close the buffer. Then you've used any variables you need, you can run any function, and you still have the HTML syntax highlighting available in your IDE.
Here's what I mean:
Template File:
<?php echo "plain text and now a function: " . testfunction(); ?>
Script:
<?php
ob_start();
include "template_file.php";
$output_string = ob_get_contents();
ob_end_clean();
echo $output_string;
?>
So the script includes the template_file.php into its buffer, running any functions/methods and assigning any variables along the way. Then you simply record the buffer's contents into a variable and do what you want with it.
That way if you don't want to echo it onto the page right at that second, you don't have to. You can loop and keep adding to the string before outputting it.
I think that's the best way to go if you don't want to use a templating engine.
found nice solution with wrapping function here: http://blog.nazdrave.net/?p=626
function heredoc($param) {
// just return whatever has been passed to us
return $param;
}
$heredoc = 'heredoc';
$string = <<<HEREDOC
\$heredoc is now a generic function that can be used in all sorts of ways:
Output the result of a function: {$heredoc(date('r'))}
Output the value of a constant: {$heredoc(__FILE__)}
Static methods work just as well: {$heredoc(MyClass::getSomething())}
2 + 2 equals {$heredoc(2+2)}
HEREDOC;
// The same works not only with HEREDOC strings,
// but with double-quoted strings as well:
$string = "{$heredoc(2+2)}";
This snippet will define variables with the name of your defined functions within userscope and bind them to a string which contains the same name. Let me demonstrate.
function add ($int) { return $int + 1; }
$f=get_defined_functions();foreach($f[user]as$v){$$v=$v;}
$string = <<< heredoc
plain text and now a function: {$add(1)}
heredoc;
Will now work.
I think using heredoc is great for generating HTML code. For example, I find the following almost completely unreadable.
<html>
<head>
<title><?php echo $page_title; ?></title>
</head>
<body>
<?php echo getPageContent(); ?>
</body>
However, in order to achieve the simplicity you are forced to evaluate the functions before you start. I don't believe that is such a terrible constraint, since in so doing, you end up separating your computation from display, which is usually a good idea.
I think the following is quite readable:
$page_content = getPageContent();
print <<<END
<html>
<head>
<title>$page_title</title>
</head>
<body>
$page_content
</body>
END;
Unfortunately, even though it was a good suggestion you made in your question to bind the function to a variable, in the end, it adds a level of complexity to the code, which is not worth, and makes the code less readable, which is the major advantage of heredoc.
you are forgetting about lambda function:
$or=function($c,$t,$f){return$c?$t:$f;};
echo <<<TRUEFALSE
The best color ever is {$or(rand(0,1),'green','black')}
TRUEFALSE;
You also could use the function create_function
This is a little more elegant today on php 7.x
<?php
$test = function(){
return 'it works!';
};
echo <<<HEREDOC
this is a test: {$test()}
HEREDOC;
I'd take a look at Smarty as a template engine - I haven't tried any other ones myself, but it has done me well.
If you wanted to stick with your current approach sans templates, what's so bad about output buffering? It'll give you much more flexibility than having to declare variables which are the string names of the functions you want to call.
A bit late but still.
This is possible in heredoc!
Have a look in the php manual, section "Complex (curly) syntax"
Here a nice example using #CJDennis proposal:
function double($i)
{ return $i*2; }
function triple($i)
{ return $i*3;}
$tab = 'double';
echo "{$tab(5)} is $tab 5<br>";
$tab = 'triple';
echo "{$tab(5)} is $tab 5<br>";
For instance, a good use for HEREDOC syntax is generate huge forms with master-detail relationship in a Database. One can use HEREDOC feature inside a FOR control, adding a suffix after each field name. It's a typical server side task.
Guys should note that it also works with double-quoted strings.
http://www.php.net/manual/en/language.types.string.php
Interesting tip anyway.
<div><?=<<<heredoc
Use heredoc and functions in ONE statement.
Show lower case ABC="
heredoc
. strtolower('ABC') . <<<heredoc
". And that is it!
heredoc
?></div>
<?php
echo <<<ETO
<h1>Hellow ETO</h1>
ETO;
you should try it . after end the ETO; command you should give an enter.

How to use PHP on file_get_contents data [duplicate]

I am designing my own MVC pattern to ease the process of creating homepages. My templating system needs my controller class to output my views. This means I have to output the file through a php function. I have been searching for some a while now and can't seem to find a solution.
How can I, through a PHP function, run a string representing some source code ("< ?", "< ?php", "? >" and so on) as php? Eval would not take my < ? signs (and I read that function is crap for some reason).
You could execute the php code and collect the output like this:
ob_start();
include "template.phtml";
$out1 = ob_get_clean();
http://www.php.net/manual/de/function.ob-get-contents.php
Just include()ing the file instead should be fine. I've not dug that deeply into the source code but I'm fairly sure that's how Zend Framework implements templates.
Replacing "echo file_get_contents()" with "include()" as GordonM suggested worked exactly as needed. can't upvote yet since I'm too new but for my needs this is the direct answer to the headlined question.
$code = '<?php
function GetBetween($content, $start, $end) {
$r = explode($start, $content);
if (isset($r[1])){
$r = explode($end, $r[1]);
return $r[0];
}
return '';
}';
function _readphp_eval($code) {
ob_start();
print eval('?>'. $code);
$output = ob_get_contents();
ob_end_clean();
return $output;
}
print _readphp_eval($code);
Well, eval is not crap per se, it's just easy to create a security hole with that if you're not careful about what you allow inside that eval (that, and maybe the fact that it can be bad for readability of the code).
As for the <? signs, that's because eval expects php code, so if you wan't to mix php with plain output, include just the closing ?> tag.
In general however, you can implement templates in better fashion, try to look into output buffering.

PHP - Is there a way to "include" a string as a file?

There is a known way to include a file and capture its contents into a string while loading.
$string = get_include_contents('somefile.php');
function get_include_contents($filename) {
if (is_file($filename)) {
ob_start();
include $filename;
return ob_get_clean();
}
return false;
}
https://www.php.net/manual/en/function.include.php
Is there a way to "include" contents loading them from a string instead of a file?
I mean something like this:
$string = file_get_contents("file.php");
include_from_string($string);
If you want the string to be parsed as PHP code, just like the contents of a file loaded with include(), then the function you need is eval().
Note that, unlike code loaded by include(), code executed by eval() automatically starts in PHP mode, so you don't need to (and shouldn't!) prefix it with <?php. If you want to emulate the behavior of include() exactly, you can prefix the string to be eval()ed with ?> to leave PHP mode:
$string = file_get_contents( 'somefile.php' );
eval( '?>' . $string );
Also note that eval() is a very dangerous function to play with! While in this specific case it shouldn't be any more risky than include() itself is, using eval() on any string that might even possibly contain unsanitized (or insufficiently sanitized) user input is extremely dangerous, and may be exploited by attackers to execute malicious code on your system and thereby gain control of it.
This might not be what you are looking for but I got "work around" for it.
Just create temporary file with tempnam() which you will include and then unlink().
$path = "somefile.php";
$stringFile = file_get_contents($path);
$pathTmp = tempnam("tmp/", ""); // you pass directory in which you will store tmp files for me it's "tmp/"
$file = fopen($pathTmp, "w+");
fwrite($file,$widget);
fclose($file);
include $pathTmp; // include the file, and PHP will be automatically parsed
unlink($pathTmp); // delete file
THIS IS WRONG:
I'm not sure if it's good practice (but hack damn, it's simple) because no one suggested it but it's better then eval() which is basically "code hazard".
THIS IS RIGHT:
As #Chris Harrison commented this is security risk and it's equal to eval(). So you could basically do this:
eval($string);
This is a simple example for you, if you pass inside the eval() this will execute the code in the string variable.
<?php
//here your PHP Code goes
$string = get_include_contents('somefile.php');
//evaluating the string this will work
eval($string); //output
This is not equivalent to using include. Here's the problem: eval() takes the provided PHP, and executes it in the current environment. Thus, any globals, functions, classes, what-not, you have defined prior to the eval() are available for the processor. This is all good, and, upon return, the only thing left of the original (evel'd) string are the results of any echo (or equivalent) statements.
This is NOT the same as an include. There the file contents are merged with your source code and that is passed to eval(). Very, very different. The easiest way to see this is to define your string as 'class fu { static function bar() { echo "wow"; } ]' Put this in a file and call fu::bar() and you'll get 'wow' displayed. At the same point in your code, if you do an eval('class fu ...') and call fu::bar() from your code you'll get "Fatal error: Call to private method fu::bar() from context ..."
But, as long as you don't need to interact with the 'include' the results will appear the same.
Just echo whatever you want instead of include inside your function!
UPDATE
Your function should look like this:
$string = "Whatever";
$str = get_var($string);
function get_var($str) {
ob_start();
echo $str;
return ob_get_clean();
}

PHP: run function at certain places (preg_callback?)

I'm trying to run a function whenever there's a [%xxx%] (acting as a placeholder, if you will), e.g.:
Bla bla bla blabla. Blablabla bla bla.
[%hooray%]
Blabla hey bla bla. [%yay%] blabla bla.
I'm pretty much a PHP beginner, but I managed to crack my head through and come up with the following (yay to me - I somehow managed to understand the basics of regular expressions!):
$maintext = preg_replace("#\[%(.{1,20})%\]#", "display_products('$1')"), $maintext);
echo $maintext;
I tried working with the e modifier, I tried using preg_replace_callback, and it all does somewhat work - but I don't need the function to run before I echo the $maintext variable.
Any help on this guys?
edit
The regex isn't the issue - that's working fine. I just need to figure out how to run the function only when I echo $maintext... preg_replace_callback runs the function immediately...
Because PHP is a single threaded procedural scripting language1, it doesn't work in the way you want it to.
It is not possible to trigger the function to run only when you call echo2, what you need instead is an extra variable.
$newVariable = preg_replace_callback("#\[%(.{1,20})%\]#", function($matches) {
// Do your thang here
}, $maintext);
// $maintext remains the same as it was when you started, do stuff with it here
// When you come to output the data, do...
echo $newVariable;
There are other approaches to this problem, like wrapping the above code in a function that can be called on demand and using the output buffering callback (see footnote #2), but reading between the lines I think all of this would be overkill for what is a relatively simple problem.
For the record, I think your regex would be better if you narrow the allowed content down a it, it will potentially match characters you don't want it to. I suspect that this would be better:
#\[%(\w{1,20})%\]#
This will allow only the characters a-zA-Z0-9_ in the placeholder.
1 Others may tell you PHP is now an object oriented language, but they are wrong. It still fundamentally works the same underneath and its still a scripting language, but now provides many OO-features.
2 It is possible to do something very close to this, but it is very rarely ever a good idea and is far too advanced for dealing with this problem.
EDIT
It is important to note that when using either method to pass replacements through a callback (e modifier or preg_replace_callback()) the callback function should return the new string, rather than outputting it directly.
This is because the code in any statement is executed from the inside out, and the "inner" echo statement (in the callback function) will be executed before the "outer" echo statement (on the line where preg_replace() is called, so the order in which things are output will be incorrect.
For example:
$str = "This is my string which contains a %placeholder%";
echo preg_replace_callback('/%(\w+)%/', function($matches) {
echo "replacement string";
}, $str);
// Wrong - outputs "replacement stringThis is my string which contains a "
echo preg_replace_callback('/%(\w+)%/', function($matches) {
return "replacement string";
}, $str);
// Right - outputs "This is my string which contains a replacement string"
If you have a script that uses echo many times and you want the printed text modified, you can use output buffering:
ob_start();
/*
* Lots of php code
*/
$maintext = ob_get_clean(); // now you capture the content in $maintext
// than you modify the output
$maintext = preg_replace("#\[%(.{1,20})%\]#", "display_products($1)", $maintext);
echo $maintext;
ob_start accepts a callback function, you can read more on this topic :
Making all PHP file output pass through a "filter file" before being displayed

Calling PHP functions within HEREDOC strings

In PHP, the HEREDOC string declarations are really useful for outputting a block of html. You can have it parse in variables just by prefixing them with $, but for more complicated syntax (like $var[2][3]), you have to put your expression inside {} braces.
In PHP 5, it is possible to actually make function calls within {} braces inside a HEREDOC string, but you have to go through a bit of work. The function name itself has to be stored in a variable, and you have to call it like it is a dynamically-named function. For example:
$fn = 'testfunction';
function testfunction() { return 'ok'; }
$string = <<< heredoc
plain text and now a function: {$fn()}
heredoc;
As you can see, this is a bit more messy than just:
$string = <<< heredoc
plain text and now a function: {testfunction()}
heredoc;
There are other ways besides the first code example, such as breaking out of the HEREDOC to call the function, or reversing the issue and doing something like:
?>
<!-- directly output html and only breaking into php for the function -->
plain text and now a function: <?PHP print testfunction(); ?>
The latter has the disadvantage that the output is directly put into the output stream (unless I'm using output buffering), which might not be what I want.
So, the essence of my question is: is there a more elegant way to approach this?
Edit based on responses: It certainly does seem like some kind of template engine would make my life much easier, but it would require me basically invert my usual PHP style. Not that that's a bad thing, but it explains my inertia.. I'm up for figuring out ways to make life easier though, so I'm looking into templates now.
If you really want to do this but a bit simpler than using a class you can use:
function fn($data) {
return $data;
}
$fn = 'fn';
$my_string = <<<EOT
Number of seconds since the Unix Epoch: {$fn(time())}
EOT;
I would not use HEREDOC at all for this, personally. It just doesn't make for a good "template building" system. All your HTML is locked down in a string which has several disadvantages
No option for WYSIWYG
No code completion for HTML from IDEs
Output (HTML) locked to logic files
You end up having to use hacks like what you're trying to do now to achieve more complex templating, such as looping
Get a basic template engine, or just use PHP with includes - it's why the language has the <?php and ?> delimiters.
template_file.php
<html>
<head>
<title><?php echo $page_title; ?></title>
</head>
<body>
<?php echo getPageContent(); ?>
</body>
index.php
<?php
$page_title = "This is a simple demo";
function getPageContent() {
return '<p>Hello World!</p>';
}
include('template_file.php');
I would do the following:
$string = <<< heredoc
plain text and now a function: %s
heredoc;
$string = sprintf($string, testfunction());
Not sure if you'd consider this to be more elegant ...
For completeness, you can also use the !${''} black magic parser hack:
echo <<<EOT
One month ago was { ${!${''} = date('Y-m-d H:i:s', strtotime('-1 month'))} }.
EOT;
See it live on 3v4l.org.
Note: PHP 8.2 deprecated bare ${} variable variables within strings, in preference to the explicit { ${} } syntax. The example above uses this explicit format to remove the deprecation notice, though it makes this method even more noisy!
Try this (either as a global variable, or instantiated when you need it):
<?php
class Fn {
public function __call($name, $args) {
if (function_exists($name)) {
return call_user_func_array($name, $args);
}
}
}
$fn = new Fn();
?>
Now any function call goes through the $fn instance. So the existing function testfunction() can be called in a heredoc with {$fn->testfunction()}
Basically we are wrapping all functions into a class instance, and using PHP's __call magic method to map the class method to the actual function needing to be called.
I'm a bit late, but I randomly came across it. For any future readers, here's what I would probably do:
I would just use an output buffer. So basically, you start the buffering using ob_start(), then include your "template file" with any functions, variables, etc. inside of it, get the contents of the buffer and write them to a string, and then close the buffer. Then you've used any variables you need, you can run any function, and you still have the HTML syntax highlighting available in your IDE.
Here's what I mean:
Template File:
<?php echo "plain text and now a function: " . testfunction(); ?>
Script:
<?php
ob_start();
include "template_file.php";
$output_string = ob_get_contents();
ob_end_clean();
echo $output_string;
?>
So the script includes the template_file.php into its buffer, running any functions/methods and assigning any variables along the way. Then you simply record the buffer's contents into a variable and do what you want with it.
That way if you don't want to echo it onto the page right at that second, you don't have to. You can loop and keep adding to the string before outputting it.
I think that's the best way to go if you don't want to use a templating engine.
found nice solution with wrapping function here: http://blog.nazdrave.net/?p=626
function heredoc($param) {
// just return whatever has been passed to us
return $param;
}
$heredoc = 'heredoc';
$string = <<<HEREDOC
\$heredoc is now a generic function that can be used in all sorts of ways:
Output the result of a function: {$heredoc(date('r'))}
Output the value of a constant: {$heredoc(__FILE__)}
Static methods work just as well: {$heredoc(MyClass::getSomething())}
2 + 2 equals {$heredoc(2+2)}
HEREDOC;
// The same works not only with HEREDOC strings,
// but with double-quoted strings as well:
$string = "{$heredoc(2+2)}";
This snippet will define variables with the name of your defined functions within userscope and bind them to a string which contains the same name. Let me demonstrate.
function add ($int) { return $int + 1; }
$f=get_defined_functions();foreach($f[user]as$v){$$v=$v;}
$string = <<< heredoc
plain text and now a function: {$add(1)}
heredoc;
Will now work.
I think using heredoc is great for generating HTML code. For example, I find the following almost completely unreadable.
<html>
<head>
<title><?php echo $page_title; ?></title>
</head>
<body>
<?php echo getPageContent(); ?>
</body>
However, in order to achieve the simplicity you are forced to evaluate the functions before you start. I don't believe that is such a terrible constraint, since in so doing, you end up separating your computation from display, which is usually a good idea.
I think the following is quite readable:
$page_content = getPageContent();
print <<<END
<html>
<head>
<title>$page_title</title>
</head>
<body>
$page_content
</body>
END;
Unfortunately, even though it was a good suggestion you made in your question to bind the function to a variable, in the end, it adds a level of complexity to the code, which is not worth, and makes the code less readable, which is the major advantage of heredoc.
you are forgetting about lambda function:
$or=function($c,$t,$f){return$c?$t:$f;};
echo <<<TRUEFALSE
The best color ever is {$or(rand(0,1),'green','black')}
TRUEFALSE;
You also could use the function create_function
This is a little more elegant today on php 7.x
<?php
$test = function(){
return 'it works!';
};
echo <<<HEREDOC
this is a test: {$test()}
HEREDOC;
I'd take a look at Smarty as a template engine - I haven't tried any other ones myself, but it has done me well.
If you wanted to stick with your current approach sans templates, what's so bad about output buffering? It'll give you much more flexibility than having to declare variables which are the string names of the functions you want to call.
A bit late but still.
This is possible in heredoc!
Have a look in the php manual, section "Complex (curly) syntax"
Here a nice example using #CJDennis proposal:
function double($i)
{ return $i*2; }
function triple($i)
{ return $i*3;}
$tab = 'double';
echo "{$tab(5)} is $tab 5<br>";
$tab = 'triple';
echo "{$tab(5)} is $tab 5<br>";
For instance, a good use for HEREDOC syntax is generate huge forms with master-detail relationship in a Database. One can use HEREDOC feature inside a FOR control, adding a suffix after each field name. It's a typical server side task.
Guys should note that it also works with double-quoted strings.
http://www.php.net/manual/en/language.types.string.php
Interesting tip anyway.
<div><?=<<<heredoc
Use heredoc and functions in ONE statement.
Show lower case ABC="
heredoc
. strtolower('ABC') . <<<heredoc
". And that is it!
heredoc
?></div>
<?php
echo <<<ETO
<h1>Hellow ETO</h1>
ETO;
you should try it . after end the ETO; command you should give an enter.

Categories