I have the following php code where I'm trying to generate a dynamic if condition using eval:
$categoryId = $_REQUEST['category_id'];
$locationId = $_REQUEST['location_id'];
$recordId = 1;
$criteria = [(!empty($categoryId) ? '(isInCategory($recordId, $categoryId))' : ''),
(!empty($locationId) ? '(isInLocation($recordId, $locationId))' : '')];
$check = implode(' && ', array_filter($criteria));
// $check will be
// (isInCategory($recordId, $categoryId)) && (isInLocation($recordId, $locationId))
// if $categoryId and $locationId are not empty
if(eval("return $check;"))
{
echo 'true';
}
else
{
echo 'false';
}
The problem is the entire code itself is within an eval statement so basically I'm ending up with an eval inside an eval which is throwing an error - can't really troubleshoot the error because all I get is a friendly error page so I'm assuming that is the case i.e. you cant use eval inside another eval???
I'm forced to use a propriety product so this is my limitation. Is there a way I can refactor the eval in the above if statement via some other technique.
I read some stuff about using call_user_func() but I'm new to this. Any help would be appreciated.
Related
I have a sql query that I store in a variable and I displayed. I get the contents of this with file_get_contents from another file, I would like to recover some of this code (which is html) in order to make link. More precisely retrieve the id.
My api.php
$base = mysql_connect ('localhost','root','');
mysql_select_db('administrations', $base);
if(isset($_GET['cp']))
{
$sql = 'SELECT NOM_organisme, ID_organisme
FROM organismes
WHERE code_postal LIKE "%'.$_GET['cp'].'%"
ORDER BY NOM_organisme;';
$req = mysql_query($sql) or die('SQL Error !<br>'.$sql.'<br />'.mysql_error());
}
while ($data = mysql_fetch_array($req))
{
echo '<p id="'.$data['ID_organisme'].'"'.
$data['NOM_organisme'].'</br>'.
$data['ID_organisme'].'</p></br>';
}
I want to get the id="I WANT THIS".
And my index.php (part of my code that retrieves the contents).
if(isset($_POST['cp']))
{
$api = "http://mywebsite.fr/api.php?cp=".$_POST['cp'];
$var = file_get_contents($api);
echo $var;
}
How can I get the id="" in my index.php ?
please look at php get documentation. you need to link to your script with url parameters and access them in your php code.
http://php.net/manual/en/reserved.variables.get.php
echo ''.$data['NOM_organisme'].'</br>'.$data['ID_organisme'].'</br>';
php
if(isset($_GET['id']))
{
$api = "http://mywebsite.fr/api.php?cp=".$_GET['id'];
$var = file_get_contents($api);
echo $var;
}
if you dont want to use url parameter you can use post values
http://php.net/manual/en/reserved.variables.post.php
I understand what your trying to do, but dont find it logical without knowing the purpose of this tiny code :)
Do you have a link or some sort?
Basicly what i should do is:
$base = mysql_connect ('localhost','root','');
mysql_select_db('administrations', $base);
if(isset($_POST['cp']))
{
$sql = 'SELECT NOM_organisme, ID_organisme FROM organismes WHERE code_postal LIKE "%'.$_GET['cp'].'%" ORDER BY NOM_organisme;';
$req = mysql_query($sql) or die('SQL Error !<br>'.$sql.'<br />'.mysql_error());
while ($data = mysql_fetch_array($req))
{
echo '<p id="'.$data['ID_organisme'].'"'.$data['NOM_organisme'].'</br>'.$data['ID_organisme'].'</p></br>';
}
} else {
echo 'show something else';
}
If I get you correctly, you are
Sending a GET request in index.php using file_get_contents() to your website.
The website (api.php) performs an SQL query and prints the result in HTML.
index.php takes this HTML output and stores it in the variable $var.
You want to retrieve all values contained inside the id attribute of the paragraph.
In this case, you probably want to use regular expressions. preg_match_all seems to be appropriate. It should work for you like this:
$out = array();
preg_match_all("/id=\"([^\"]*?)\"/U", $var, $out);
foreach ($out as $value) {
echo 'I found some id ' . htmlspecialchars($out[$value][2]) . '<br />';
}
And additionally:
A decent HTML parser would be much more appropriate in this case (eg. it would not match id="X" in flow text).
Your PHP code is vulnerable to SQL injections.
You should sanitize plain text to HTML appropriately.
First of all, you should try to display your API reply as a JSON-string, this is much more convenient.
If you still want to use your api.php, you first need to close your opening paragraph! You did forget a '>'!
echo '<p id="'.$data['ID_organisme'].'">'.
$data['NOM_organisme'].'</br>'.
$data['ID_organisme'].'</p></br>';
Then you need to parse your paragraph.
You can do it like that:
if(isset($_POST['cp']))
{
$api = "http://mywebsite.fr/api.php?cp=".$_POST['cp'];
$var = file_get_contents($api);
preg_match("#<p id='(.*)'#", $var, $matches);
id = $matches[1];
echo $id;
}
I'm building a dynamic website, but the pages are not showing up because of the error
Fatal error: Function name must be a string php
on the line
$p= $_GET('p');
The whole code for including the files is
$folder = 'de/';
$folder = 'en/';
if(!empty($_GET['p'])){
$pages = scandir($folder,0);
unset($pages[0],$pages[1]);
$p= $_GET('p');
if(in_array($p.'.inc.php', $pages)){
include($folder.'/'.$p.'.inc.php');
}else{
echo 'error message';
}
}else{
include($folder.'home.inc.php');
}
What's wrong with my code?
UPDATE
I've updated the code, but now i get the error
*failed to open stream: No such file or directory*
I'm working on a local server.
$p= $_GET('p');
should be
$p= $_GET['p'];
Your code is quite inefficient. Why slurp up the directory's contents into an array and then search the array when you could simply have:
if (isset($_GET['p']) {
$file = $folder . $_GET['p'] .'.inc.php';
if (is_readable($file)) {
include($file);
} else {
die('error');
}
} else {
include($folder.'home.inc.php');
}
This is BY FAR simpler than your convoluted logic. It is however, also vulnerable to the exact same vulnerability: you're allow the user to specify a full path to ANY *.inc.php file on your server for which they know the path name. Depending on your setup, this could allow the user to include files which you ever intended to be executed in this manner and leak internal details of your system/configuration.
$p= $_GET('p');
You really didn't notice that you were using parenthesis?
Use:
$p = $_GET['p'];
$p= $_GET('p'); it should be $p= $_GET['p'];
The error seems $_GET('p') should be $_GET['p'] instead.
A few considerations:
The if(!empty($_GET['p'])), could be changed to if (array_key_exists('p', $_GET) && !empty($_GET['p']) instead. PHP always complain about array indexes and it's a good way to prevent it.
on unset($pages[0],$pages[1]);, if the array doesn't return 2 elements, it will return null and PHP unset function will complain. A better way could you check if there are elements on $pages variable;
In case of scandir doesn't return any element, not sure if it'll return null or array, so in this case if(in_array($p.'.inc.php', $pages)) will throw a error.
Cheers
I'm just learning PHP, and I'm sure I'm not the first person to try something like this, but maybe because I didn't know what to call it, I couldn't find any other examples or questions on here or from a search on google.
I wanted to create a function which takes two parameters and uses them to create all the short style variables I'll be using later in my script.
My problem is where normally the syntax to create a short variable is something like:
$var = $_METHOD['var'];
but I'm trying to do this using variables and don't know how to get the syntax right. Here's my code:
<?php
session_start();
function shortnames($some_vars, $type) {
for ($i = 0; $i<(count($some_vars)); $i++) {
$$some_vars[$i] = $_$type['$some_vars[$i]'];
echo $$some_vars[$i].' = '.$some_vars[$i].'<br />';
}
}
$post_vars = array(lastname,firstname,payment);
$session_vars = array(sessiontxt,province,city,venue,regfee);
shortnames($session_vars,session);
shortnames($post_vars,post);
?>
Thanks for helping a beginner!!
I'm working on a project where the admin panel is just a shell that do some actions depending on what string you input.
By shell i mean an input box where you type for example
delete user 1
and the user with id 1 is deleted.
I have planned this for about 4 months and i have written all the commands that the app could manage.
I have some problem to make this system. I was thinking about this solution:
$c = explode(' ', $input);
if ($c[0] == 'delete' and $c[1] == 'user' and count($c) === 3)
{
$c[2] = $id;
delete_user_by_id($id);
}
But i think it is not that well designed and i'm sure that it could be improved.
I noticed that exists regular expression and that they could be better than this but i can't really figure out how to use them in the previous example.
Any idea?
{Notice that a part of the string is variable (delete user VARIABLE)}
Instead of a bunch of if statements, you should create a class for each command, which takes the information as an argument and does something. You just need to load the class when it's called.
$command = 'delete user 1';
$parsed = explode($command, ' ', 2);
load_class($parsed[0]); // hypothetical loader
if (class_exists($parsed[0])) {
$class = new $parsed[0]();
$class->execute($parsed[1]);
} else {
die('Sorry, invalid command');
}
I think exploding on spaces is cleaner than using a regex.
You might be able to clean up the code a bit with a switch statement, and trimming the input before you explode it:
$c explode(' ', trim($input));
switch(strtolower($c)) {
case 'delete' :
delete_user_by_id($c[2]);
break;
case 'update' :
update_user_by_id($c[2]);
break;
...
default :
echo 'Invalid command: '.$c;
}
<?php echo isset($areas['footer']) ? $areas['footer'] : null; ?>
Any way to improve that?
Note that you are echoing and in false condition it would be null which does not have any effect. You could say like 'empty' or ' ' or 'not found' instead. Other alternative is to get the return value of isset:
$return = isset($areas['footer']) ? $areas['footer'] : null;
if ($return)
{
// $return contains footer info
}
else
{
// footer was not set :(
}
Depending on where $areas comes from it might be cleaner to assign it to a variable:
$footer = isset($areas['footer']) ? $areas['footer'] : null;
Then you can use $footer without any additional isset checks.
You can also spare the else branch, by setting a default:
$footer = null;
if (isset($areas['footer'])) {
$footer = $areas['footer'];
}
echo $footer;
No, this is the most concise way of handling this sort of output.
"i'm using this kind of code very often"
Maybe you should avoid the issue altogether by using a template language, or encapsulating this behavior in a function?
like this:
function get_area($area) {
if... //your code
return $area
One shorter version i can think of would be:
<?php !isset($areas['footer']) or print $areas['footer']; ?>
But i'm not sure if it is faster or more elegant.
What do you guys think?
echo $areas['footer'];
Simple and has the exact same effect as the original line.
Edit in reply to Felix
This gives a notice, but unless you're supposed to turn this in as ultra-perfect homework, it doesn't really matter. You can either fill your code with isset calls or ignore small stuff like this. I'd worry about it if I was working in say... Java, but pragmatically nobody is going to care if PHP code that works produces notices.