php error Function name must be a string php - php

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

Related

Dynamically created directory returns "Array" 1 in 1000 times

I'm fixing up some old code that is supposed to create a directory for a customer based on the customer's last name. 999 out of 1000 times it works as expected but every now and then I get an "Unable to create base directory" error message and the debug shows me that the $file_directory in that case is simply "Array" instead of something like "\\network\path\order_data\1234567890_Smith".
Could anyone explain how this code could work the vast majority of the time but still consistently fail about .1% of instances? Or is it something other than the code? Thanks!
Note: I did not originally write this code but am tring to leave it as close to the original as possible
Edit I had a typo in my previous code but I think tliokos and Fluinc had a very good point but just wanted to fix my mistake
Code:
<?php
$file_directory = build_directory($customer, $UID);
if(!is_dir($file_directory)){ //Check to make sure it does not already exist
if(!mkdir($file_directory)){
mail("debug#example.com","Unable to create base directory","$file_directory");
}
}
function build_directory($customer, $UID){
if($customer->related_orders){
$related = explode(",", $customer->related_orders);
foreach($related as $r_UID){
$rel_order = get_order($r_UID); //fetches order object
if((isset($rel_order->file_directory) && $rel_order->file_directory != "")){
return $rel_order->file_directory;
}
}
}
//Here is where I made my correction
$paths = array('\\\\network\\path');
$base = $paths[0];
//Test if directory is already assigned
if(is_dir($base . "\\order_data\\".$UID."_".str_replace(" ","_",$customer->last_name)."\\")){
return $base . "\\order_data\\".$UID."_".str_replace(" ","_",$customer->last_name)."\\";
}
if($base){
return $base . "\\order_data\\".$UID."_".str_replace(" ","_",$customer->last_name)."\\";
}
}
?>
Change $base = array('\\network\path');
To $base = '\\network\path';
I think the problem is in the build_directory() function and more specifically after the first if.
So if the customer has no related orders, you are trying to concatenate an Array with a string and the result is like
Array\order_data\....
Try o change
$base = array('\\network\path');
to
$base = '\\network\path';
So the problem ended up being framework/user related.
We discovered that if the user refreshed the page during the directory creation it would create the same directory twice which our framework would save as an array of identical paths.

image_container remains null therefore it throws the error? [duplicate]

I am using this library (PHP Simple HTML DOM parser) to parse a link, here's the code:
function getSemanticRelevantKeywords($keyword){
$results = array();
$html = file_get_html("http://www.semager.de/api/keyword.php?q=". urlencode($keyword) ."&lang=de&out=html&count=2&threshold=");
foreach($html->find('span') as $e){
$results[] = $e->plaintext;
}
return $results;
}
but I am getting this error when I output the results:
Fatal error: Call to a member function find() on a non-object in
/var/www/vhosts/efamous.de/subdomains/sandbox/httpdocs/getNewTrusts.php
on line 25
(line 25 is the foreach loop), the odd thing is that it outputs everything (at least seemingly) correctly but I still get that error and can't figure out why.
The reason for this error is: the simple HTML DOM does not return the object if the size of the response from url is greater than 600000.
You can void it by changing the simple_html_dom.php file. Remove strlen($contents) > MAX_FILE_SIZE from the if condition of the file_get_html function.
This will solve your issue.
You just need to increase CONSTANT MAX_FILE_SIZE in file simple_html_dom.php.
For example:
define('MAX_FILE_SIZE', 999999999999999);
This error usually means that $html isn't an object.
It's odd that you say this seems to work. What happens if you output $html?
I'd imagine that the url isn't available and that $html is null.
Edit:
Looks like this may be an error in the parser. Someone has submitted a bug and added a check in his code as a workaround.
Before file_get_html/load_file method, you should first check if URL exists or not.
If the URL exists, you pass one step.
(Some servers, service a 404 page a valid HTML page. which has propriate HTML page structure like body, head, etc. But it has only text "This page couldn'!t find. 404 error bla bla..)
If URL is 200-OK, then you should check whether fetched thing is object and whether nodes are set.
That's the code i used in my pages.
function url_exists($url){
if ((strpos($url, "http")) === false) $url = "http://" . $url;
$headers = #get_headers($url);
// print_r($headers);
if (is_array($headers)){
if(strpos($headers[0], '404 Not Found'))
return false;
else
return true;
}
else
return false;
}
$pageAddress='http://www.google.com';
if ( url_exists($pageAddress) ) {
$htmlPage->load_file( $pageAddress );
} else {
echo 'url doesn t exist, i stop';
return;
}
if( $htmlPage && is_object($htmlPage) && isset($htmlPage->nodes) )
{
// do your work here...
} else {
echo 'fetched page is not ok, i stop';
return;
}
For those arriving here via a search engine (as I did), after reading the info (and linked bug-report) above, I started some code-prodding and ended up fixing my problems with 2 extra checks after loading the dom;
$html = file_get_html('<your url here>');
// first check if $html->find exists
if (method_exists($html,"find")) {
// then check if the html element exists to avoid trying to parse non-html
if ($html->find('html')) {
// and only then start searching (and manipulating) the dom
}
}
I'm having the same error come up in my logs and apart from the solutions mentioned above, it could also be that there is no 'span' in the document. I get the same error when searching for divs with a particular class that doesn't exist on the page, but when searching for something that I know exists on the page, the error doesn't pop up.
your script is OK.
I receive this error when it doase not find the element that i'm looking for on that page.
In your case, please check if the page that you are accessing it has 'SPAN' element
Simplest solution to this problem
if ($html = file_get_html("http://www.semager.de/api/keyword.php?q=". urlencode($keyword) ."&lang=de&out=html&count=2&threshold=") {
} else {
// do something else because couldn't find html
}
Error means, the find() function is either not defined yet or not available. Make sure you have loaded or include related function.

SimpleHtmlDOM, PHP, Fatal Error: Call to a member function find() on a non-object in C:\xampp\htdocs [duplicate]

I am using this library (PHP Simple HTML DOM parser) to parse a link, here's the code:
function getSemanticRelevantKeywords($keyword){
$results = array();
$html = file_get_html("http://www.semager.de/api/keyword.php?q=". urlencode($keyword) ."&lang=de&out=html&count=2&threshold=");
foreach($html->find('span') as $e){
$results[] = $e->plaintext;
}
return $results;
}
but I am getting this error when I output the results:
Fatal error: Call to a member function find() on a non-object in
/var/www/vhosts/efamous.de/subdomains/sandbox/httpdocs/getNewTrusts.php
on line 25
(line 25 is the foreach loop), the odd thing is that it outputs everything (at least seemingly) correctly but I still get that error and can't figure out why.
The reason for this error is: the simple HTML DOM does not return the object if the size of the response from url is greater than 600000.
You can void it by changing the simple_html_dom.php file. Remove strlen($contents) > MAX_FILE_SIZE from the if condition of the file_get_html function.
This will solve your issue.
You just need to increase CONSTANT MAX_FILE_SIZE in file simple_html_dom.php.
For example:
define('MAX_FILE_SIZE', 999999999999999);
This error usually means that $html isn't an object.
It's odd that you say this seems to work. What happens if you output $html?
I'd imagine that the url isn't available and that $html is null.
Edit:
Looks like this may be an error in the parser. Someone has submitted a bug and added a check in his code as a workaround.
Before file_get_html/load_file method, you should first check if URL exists or not.
If the URL exists, you pass one step.
(Some servers, service a 404 page a valid HTML page. which has propriate HTML page structure like body, head, etc. But it has only text "This page couldn'!t find. 404 error bla bla..)
If URL is 200-OK, then you should check whether fetched thing is object and whether nodes are set.
That's the code i used in my pages.
function url_exists($url){
if ((strpos($url, "http")) === false) $url = "http://" . $url;
$headers = #get_headers($url);
// print_r($headers);
if (is_array($headers)){
if(strpos($headers[0], '404 Not Found'))
return false;
else
return true;
}
else
return false;
}
$pageAddress='http://www.google.com';
if ( url_exists($pageAddress) ) {
$htmlPage->load_file( $pageAddress );
} else {
echo 'url doesn t exist, i stop';
return;
}
if( $htmlPage && is_object($htmlPage) && isset($htmlPage->nodes) )
{
// do your work here...
} else {
echo 'fetched page is not ok, i stop';
return;
}
For those arriving here via a search engine (as I did), after reading the info (and linked bug-report) above, I started some code-prodding and ended up fixing my problems with 2 extra checks after loading the dom;
$html = file_get_html('<your url here>');
// first check if $html->find exists
if (method_exists($html,"find")) {
// then check if the html element exists to avoid trying to parse non-html
if ($html->find('html')) {
// and only then start searching (and manipulating) the dom
}
}
I'm having the same error come up in my logs and apart from the solutions mentioned above, it could also be that there is no 'span' in the document. I get the same error when searching for divs with a particular class that doesn't exist on the page, but when searching for something that I know exists on the page, the error doesn't pop up.
your script is OK.
I receive this error when it doase not find the element that i'm looking for on that page.
In your case, please check if the page that you are accessing it has 'SPAN' element
Simplest solution to this problem
if ($html = file_get_html("http://www.semager.de/api/keyword.php?q=". urlencode($keyword) ."&lang=de&out=html&count=2&threshold=") {
} else {
// do something else because couldn't find html
}
Error means, the find() function is either not defined yet or not available. Make sure you have loaded or include related function.

Need better structure of my code

this is my front controller
$pages = array("matches", "boards", "search", "articles", "interviews", "userlist", "teams", "servers", "awards", "gallery", "qids");
if (!$_SERVER['QUERY_STRING']) include('home_en.php');
elseif (isset($_GET['matchid'])) include('matchid.php');
elseif (isset($_GET['boardid'])) include('boardid.php');
elseif (isset($_GET['articleid'])) include('articleid.php');
elseif (isset($_GET['interviewid'])) include('interviewid.php');
elseif (isset($_GET['userid'])) include('profi.php');
elseif (isset($_GET['teamid'])) include('teamid.php');
elseif (isset($_GET['serverid'])) include('serverid.php');
elseif (isset($_GET['awardid'])) include('awardid.php');
elseif (isset($_GET['galleryid'])) include('galleryid.php');
elseif (isset($_GET['threadid'])) include('threadid.php');
elseif (isset($_GET['blogid'])) include('blogid.php');
..
elseif (in_array($_GET['content'], $pages)) include($_GET['content']);
else echo "File not found =(";
could i somehow add the identifiers to the array too? but i want the pages as index.php?matchid=9438 and for regular pages: index.php?content=matches
would really aprricate some ideas
thanks!
My Suggestion, From My Comment is this:
In order to check what type of id it is, you should use two $_GET parameters. One is the type (match, award, server, etc), one is the ID. That way you don't have to check for 500 different $_GET parameters, just the value of 2. Much more standardized.
Second, you want to make all of it under 1 file for the ID showing.
In the spirit of writing less code, not more, it would be relatively easy to change the SQL statement to grab the record based on if $_GET['type'] was match, award, team, etc. This is of course given that they will probably look the same. If they don't, instead of writing new code to grab each type, instead write code to display it differently
All Variables in this code much be validated/sanatized beforehand.
// First Get the Type
$type = $_GET['type'];
// Then the ID
$id = $_GET['id'];
// SANITIZE YOUR DATA. Replace this with your sanitization.
die("SANITIZE YOUR DATA HERE");
// Get Data Here
$sql = "SELECT * FROM table WHERE type=".$type." AND id=".$id;
$data = mysql_query($sql);
// Next, Include a template based on the data.
// Global the variable so it can be used in the file
Global $data;
include($type."-template.php");
I agree with Tom -- you should look into using a framework such as Zend, Cake, Symfony, Kohana, CodeIgniter, ez-Components, or Seagull. The advantage of using a framework is that they have already solved a lot of issues for you, including:
1) How to structure your code
2) How to interpret pretty urls (i.e. /x/1/y/2 instead of ?x=1&y=2)
3) Where to put certain types of code (html, php, configs, etc)
4) How to fix something you can't figure out (because these frameworks have communities)
and much much more...
That being said, maybe you don't want all the overhead of using a framework (it does require you to learn a lot). In that case, I recommend Rasmus Lerdorf's "No Framework PHP Framework". Rasmus is the creator of PHP, so you know he knows his stuff.
Lastly, to answer your actual question, here's how I would do it:
could i somehow add the identifiers to the array too?
i want the pages as index.php?matchid=9438
and for regular pages: index.php?content=matches
Sure, but yes, as Chacha102 said, you will need 2 parameters: $area (page) and $id.
Example: index.php?area=articles&id=2345
Then you can re-organize & simplify your 'front controller' this way:
/index.php
/areas/articles.php
/areas/boards.php
etc.
Instead of naming the templates articleid.php, just call it articles.php -- this way your area name also tells you which template to use.
$valid_areas = array("matches", "boards", "search", "articles",
"interviews", "userlist", "teams", "servers",
"awards", "gallery", "qids");
$area = strtolower(trim($_REQUEST['area'])); //if you are not posting any forms, use $_GET instead
$id = (int)$_REQUEST['id']; //if you are not posting any forms, use $_GET instead
if(!$id)
{
include('home_en.php');
}
if(!in_array($area), $valid_areas))
{
echo 'Sorry, the area you have requested does not exist: '.$area;
exit();
}
else
{
$template = '/templates/'.$area.'.php';
if(!file_exists($template))
{
echo 'Sorry, the file you have requested does not exist: '.$area.' '.$id);
}
else
{
include($template);
}
}
It might help to go ahead and use a framework such as Zend:
http://framework.zend.com/
You could do this:
<?php
$controllerDefault = 'home';
function sanitize($str)
{
return str_replace(array('.', '/', '\\'), '', $str);
}
//Prevent of Remote File Inclusion
$controller = sanitize($_GET['controller']);
$id = intval($_GET['id']);
if (empty($controller))
{
$controller = $controllerDefault;
}
if (!empty($id))
{
$controller .= 'id';
}
$controllerFile = $controller . '.php';
if (!file_exists($controllerFile)
|| $controller == 'index') //for not recursive index.php include :)
{
exit('Controller "'.$controllerFile.'" not exists');
}
include($controllerFile);
?>
Using this code you can use your application like:
http://yoursite.com/index.php //include('home.php')
http://yoursite.com/index.php?id=285230 //include('homeid.php')
http://yoursite.com/index.php?controller=matches //include('matches.php')
http://yoursite.com/index.php?controller=matches&id=28410 //include('matchesid.php')
http://yoursite.com/index.php?controller=notexists //ERROR! Controller "notexists" not exists
http://yoursite.com/index.php?controller=../../etc/passwd //ERROR! Controller "etcpasswd" not exists
I hope you like it
PD: the code is not tested, but I hope you catch my idea

Phpmyadmin login script

I trying to code a login script for phpmyadmin
<?php
$user = "Domain";
$passwords = file("passwords.txt");
foreach ( $passwords as $pass){
$source = file_get_contents("http://dbadmin.one.com/index.php?lang=en&server=1&pma_username=$user&pma_password=$pass");
if(preg_match("/Database/", $source)):
echo "Login Worked with: {$pass}";
endif;
}
?>
My Problem is it , it dont works here
echo "Login Worked with: {$pass}";
Can you see the problem?
Not necessarily the solution to your problem, but some basic error checking might point you in the right direction. Your problem may even begin at the initial call to file.
$passwords = file("passwords.txt");
if (!$passwords) {
echo 'Unable to read password file';
} //etc
$source = file_get_contents("http://dbadmin.one.com/index.php?lang=en&server=1&pma_username=$user&pma_password=$pass");
if (!$source) {
echo 'Unable to read file source';
} //etc
Also as a side note if you were calling this function on a file outside your filesystem wouldn't you only get the output (HTML) similar to calling it in your browser (not sure if that was your intention).
$source = file_get_contents("http://dbadmin.one.com/index.php?lang=en&server=1pma_username=$user&pma_password=$pass");
if(preg_match("/Database/", $source)):
The value of $source is going to be the full HTML response of getting the url:
http://dbadmin.one.com/index.php?lang=en&server=1&pma_username=$user&pma_password=$pass
preg_match is only going to match on the first line of that string. You will need to parse the string differently or replace any newline characters so it will match on the whole file.
It also looks like you're testing logins to a database using the username "Domain" with a number of different passwords. Not sure if that was your intention, but it seems a bit odd.

Categories