Forum Moderators: coopster

Message Too Old, No Replies

Executing PHP code With PHP

         

brendan3eb

10:37 pm on Mar 24, 2005 (gmt 0)

10+ Year Member



I'm making a script that will allow me to have multiple layouts and have a layout selector for the end-user. I'm attempting this with SQL and the script works with plain html, however I want to have php in the layout code from mysql and have it work but it wont work. Is it possible to do what I want to do with MySQL? Here is my code:

<?php
if(@include("config.php"))
{
$sqlconnect = mysql_connect($mysqlhost, $mysqluser, $mysqlpass);
mysql_select_db($mysqldb, $sqlconnect);
$grabinfo = mysql_query("SELECT * FROM xaler_info");
$info = mysql_fetch_array($grabinfo);
extract($info);
if($_COOKIE[layout] == "")
{
$code = mysql_query("SELECT * FROM xaler_layouts WHERE name='$defaultloc'");
while($source = mysql_fetch_array($code))
{
$final_layout = preg_replace("/#layout/", "includes", $source[code]);

echo $final_layout;
}
}
else
{
if(!eregi('^[a-z]', $_COOKIE[layout]))
{
echo "We could not locate the layout";
}
else
{
$getlayouts = mysql_query("SELECT * FROM xaler_layouts");
while($all_lays = mysql_fetch_array($getlayouts))
{
if($_COOKIE[layout] == $all_lays[name])
{
$foundlayout = "yes";
$laycode = $all_lays[code];
}
}
if($foundlayout!= "yes")
{
"This layout no longer exists";
}
else
{
$final_layout = preg_replace("/#layout/", "includes", $laycode);
echo $final_layout;
}
}
}
}
else
{
echo "The Configuration File Is Missing";
}
?>

mincklerstraat

9:46 am on Mar 25, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



If a variable includes php code (like $allcode here, I presume), simply echoing it won't execute the code; it will simply output that code. For executing code, you need the function eval().

However, be forewarned that many a seasoned php coder will advise against the use of eval(). A lot of really freaky things can happen, some of them really vile. You'd want to be sure, sure, and utterly sure of the code that goes into eval() before it gets executed, to make sure these freaky things don't happen. Also, in most cases, instead of using eval(), you can use a library of functions which are called up using variables. E.g., populate an array $dostuff = array('function_1' => 'content_', 'function_2' => 'content_2'); etc - name your functions: myscript_function(), and loop through your array:
foreach($dostuff as $v){
if(function_exists('myscript_'.$v[0])) call_user_function('myscript_'.$v, $v[1]);
}
This way, the only functions which are permitted are those which begin with the myscript_ preface, so, for example, someone who got access to this part of your script could do 'print_r(file(passwords.php))';

In the days of php 4.0x, it wasn't uncommon for content management scripts to have 'php blocks', sidebars which were produced by a php snippet which the webmaster added to the database, which was then 'eval()'d. With the greater security-consciousness on the net these days, I don't think you'll find this functionality any more, most will have removed it.

brendan3eb

7:54 pm on Mar 25, 2005 (gmt 0)

10+ Year Member



w00t, thank you very very very much.

brendan3eb

12:06 am on Mar 26, 2005 (gmt 0)

10+ Year Member



I just finished trying your requested methods but ive had problems with both, here is the code I used for the functions method:

<?php
if(@include("config.php"))
{
$sqlconnect = mysql_connect($mysqlhost, $mysqluser, $mysqlpass);
mysql_select_db($mysqldb, $sqlconnect);
$grabinfo = mysql_query("SELECT * FROM xaler_info");
$info = mysql_fetch_array($grabinfo);
extract($info);
if($_COOKIE[layout] == "")
{
$code = mysql_query("SELECT * FROM xaler_layouts WHERE name='$defaultloc'");
while($source = mysql_fetch_array($code))
{
function includethis()
{
$error_file = "error.htm";
$default = "news/news.php";
if($id == "")
{
echo "includes";
}
if(isset($id))
{
if(file_exists("$id.php"))
{
include("$id.php");
}
elseif(file_exists("$id.htm"))
{
include("$id.htm");
}
else
{
include($error_file);
}
}
}
$final_layout = preg_replace("/#layout/", call_user_func('includethis'), $laycode);
echo $final_layout;
}
}
else
{
if(!eregi('^[a-z]', $_COOKIE[layout]))
{
echo "We could not locate the layout";
}
else
{
$getlayouts = mysql_query("SELECT * FROM xaler_layouts");
while($all_lays = mysql_fetch_array($getlayouts))
{
if($_COOKIE[layout] == $all_lays[name])
{
$foundlayout = "yes";
$laycode = $all_lays[code];
}
}
if($foundlayout!= "yes")
{
"This layout no longer exists";
}
else
{
function includethis()
{
$error_file = "error.htm";
$default = "news/news.php";
if($id == "")
{
include($default);
}
if(isset($id))
{
if(file_exists("$id.php"))
{
include("$id.php");
}
elseif(file_exists("$id.htm"))
{
include("$id.htm");
}
else
{
include($error_file);
}
}
}
$final_layout = preg_replace("/#layout/", includethis(), $laycode);
}
}
}
}
else
{
echo "The Configuration File Is Missing";
}
?>

but that just outputs "includes" and doesnt show the layout code from mysql. I also messed around with eval, but take for instance this code:

<?php
$this = "I am going to replace this #word";
$this = preg_replace("/#word/", eval("echo \"food\";"), $this);
echo $this;
?>

it outputs "foodI am going to replace this".

Other than this, thanks for the help, I've only been messing around with functions for an hour now, if no one makes a post I'll hopefully come up with a solution by tommorow :)

mincklerstraat

10:07 am on Mar 26, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Yeah, you would have had problems with my code since the array I suggested and the function I suggested aren't compatible. This is one of the sticky things with arrays - there are so many different ways to make arrays carry your information in a meaningful way that can be looped through that sometimes you'll find you've created your information in one format, but are trying to call it up in another.

Anyways, with an array like I posted, the keys are the functions, and the values are the content (what gets passed as an arg)
$array = array(
'make_header' => '',
'output_stuff' => 'Welcome to my groovy site',
'show_rss_feed' => 'http://example.com',
'make_menu_from_directory' => '/articlecontent/',
'grab_and_display_article' => 48);
You use this array because you have your little function library with functions, each beginning with a unique preface, that take the 'content' part (the value) of the array as an argument - these functions are the key names - so you have functions like
function mysite_make_header($arg){
echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>my groovy site</title>
</head>
<body>';
} // notice - just ignores $arg
function mysite_output_stuff($arg){
echo htmlspecialchars($arg);
}
function mysite_grab_and_display_article($arg){
$content = file_get_contents('articles/'.$arg.'.php');
echo htmlspecialchars($content);
}
functions like that, with 'mysite_' or your unique preface to keep this from accessing normal php functions. Then the loop that actually executes this all looks like this:
foreach($array as $k => $v){
if(function_exists('mysite_'.$k)) call_user_func('mysite_'.$k, $v);
else die('function mysite_'.htmlspecialchars($k).' does not exist');
}

brendan3eb

8:57 pm on Mar 26, 2005 (gmt 0)

10+ Year Member



So if I were to use the method you showed in your last post, I'd have to divide layouts into different parts?

mincklerstraat

4:36 pm on Mar 27, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



This way of doing things just helps you have a more flexible way of calling code somewhat arbitrarily, without making *all* the php functions available, like you have with eval (which is what makes it so potentially dangerous) - say you have a sidebar that you want highly customizable, you can plop in this type of code there, and then have a means of generating the array and adding it to the database. It's still pretty advanced coding, though, and likely to be a huge pain if you're not really familliar with every part of it - few cms systems would go to the pain of this type of coding.

In general, if you can just avoid eval(), and avoid systems like this for giving you extra flexible code (which usually also brings its extra dose of bugs to deal with), and just use 'normal' control structures like dynamic includes (include 'dir/'.$var.'.php'; - after you've checked $var to make sure it's 'ok' to include), switch structures, or the ole classic if / then, you save yourself a whole lot of grief. However, if you really feel like you need eval(), chances are you're working with something that doesn't fit nicely into the classical control structures.

Good luck however you manage it.

brendan3eb

6:26 pm on Mar 28, 2005 (gmt 0)

10+ Year Member



Thanks for all the help, I found a method using eval(), for what I'm doing I believe it should be safe. I took the layout code from mysql, and did something like below
$final_code = "echo \"".$layout_code."\";";
eval($final_code);
and I replaced <?php's and?>'s woth ";'s and echo "'s. Once again thanks for the help.