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
Related
I have a problem with PHP's strip_tags function. I have a list which includes a whitelist for html tags. That list is generated from a function like:
setAllowedHtmlTags();
and output for this function is:
"<a><table><br>"
I want to eliminate other html tags but this. Therefore I use strip_tags function as follows:
echo strip_tags("sample text", setAllowedHtmlTags());
And here is my function:
function setAllowedHtmlTags()
{
$db = new PDO('mysql:host=' . host . ';dbname=' . DBNAME_SCHEMA, user, password);
$sql = "SELECT html_tag FROM allowed_html_tags_table";
$query = $db->query($sql);
$tagList = "";
if ($query->rowCount()){
foreach($query as $row){
$tagList .= $row['html_tag'];
}
}
return htmlentities($tagList);
}
But it does not work. strip_tags function removes all html tags including mines in my whitelist. Can you please help me solve this issue?
Ok I found the problem, returning the value with html_entity_decode() function instead htmlentities() function worked for me.
Does your function setAllowedHtmlTags() really return what you told us?
Try a var_dump(setAllowedHtmlTags()); to see what the function really returns.
Or maybe you wanted to call getAllowedHtmlTags()?
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);
I have looked at a couple of questions here, and done a Google search but I cannot seem to find the correct way to go about doing this.
I am using this function
function replace_c($content){
global $db;
$replacements = $db->query("SELECT * FROM `replacements`");
while($replace = $replacements->fetch_assoc()){
preg_replace("/".$replace['triggers']."/i",$replace['php'], $content);
}
return $content;
}
and this is my call to the function
$contents = replace_c(file_get_contents("templates/" . $settings['theme'] . "/header.html"));
It doesn't give an error, it just doesn't replace the text like it should so I am not sure if the function is actually working. I did try preg_replace_callback but I don't think I fully understand how it works and was producing nothing but errors, do I have to go the callback route, or am I just missing something in my current function?
Kira,
The preg_Replace function returns the replaced string. The $content subject you post to it will not update as a reference. So try changing the code to;
$content = preg_replace("/".$replace['triggers']."/i",$replace['php'], $content);
You never assign the return value of preg_replace to $content.... What you need is this:
$content = preg_replace("/".$replace['triggers']."/i",$replace['php'], $content);
You need to store the replaced content back to a variable.
$content = preg_replace(...);
Also, are you sure that an str_replace() wouldn't be enough?
For reasons I'd rather not get into right now, I have a string like so:
<div>$title</div>
that gets stored in a database using mysql_real_escape_string.
During normal script execution, that string gets parsed and stored in a variable $string and then gets sent to a function($string).
In this function, I am trying to:
function test($string){
$title = 'please print';
echo $string;
}
//I want the outcome to be <div>please print</div>
This seems like the silliest thing, but for the life of me, I cannot get it to "interpret" the variables.
I've also tried,
echo html_entity_decode($string);
echo bin2hex(html_entity_decode($string)); //Just to see what php was actually seeing I thought maybe the $ had a slash on it or something.
I decided to post on here when my mind kept drifting to using EVAL().
This is just pseudocode, of course. What is the best way to approach this?
Your example is a bit abstract. But it seems like you could do pretty much what the template engines do for these case:
function test($string){
$title = 'please print';
$vars = get_defined_vars();
$string = preg_replace('/[$](\w{3,20})/e', '$vars["$1"]', $string);
echo $string;
}
Now actually, /e is pretty much the same as using eval. But at least this only replaces actual variable names. Could be made a bit more sophisticated still.
I don't think there is a way to get that to work. You are trying something like this:
$var = "cute text";
echo 'this is $var';
The single quotes are preventing the interpreter from looking for variables in the string. And it is the same, when you echo a string variable.
The solution will be a simple str_replace.
echo str_replace('$title', $title, $string);
But in this case I really suggest Template variables that are unique in your text.
You just don't do that, a variable is a living thing, it's against its nature to store it like that, flat and dead in a string in the database.
If you want to replace some parts of a string with the content of a variable, use sprintf().
Example
$stringFromTheDb = '<div>%s is not %s</div>';
Then use it with:
$finalString = sprintf($stringFromTheDb, 'this', 'that');
echo $finalString;
will result in:
<div>this is not that</div>
If you know that the variable inside the div is $title, you can str_replace it.
function test($string){
$title = 'please print';
echo str_replace('$title', $title, $string);
}
If you don't know the variables in the string, you can use a regex to get them (I used the regex from the PHP manual).
function test($string){
$title = 'please print';
$vars = '/(?<=\$)[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/';
preg_match_all($vars, $string, $replace);
foreach($replace[0] as $r){
$string = str_replace('$'.$r, $$r, $string);
}
echo $string;
}
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.