Looking through the server PHP error log has revealed that a certain type of PHP Notices comes up as the most frequent, and it has to do with Smarty. I've found a question which seems to describe the same error, but there is actually no answer.
The notice is the following (there are different variables stated as undefined):
PHP Notice: Undefined variable: is_admin in /usr/share/php/Smarty/sysplugins/smarty_internal_data.php on line 291
I wonder how I can possibly debug this one since no data (like template name) is provided.
Below I'm gonna give you some idea of the code (which you can read in full detail here since it's all open-source).
So there is one global smarty object which is created in a file called header.php, and further in the same file some global smarty variables are set, including the one from the notice above:
//init Smarty
require_once('Smarty.class.php');
$smarty = new Smarty();
...
$smarty->assign('is_admin', is_admin() ? 1 : 0);
This header.php is then included in every file that needs to show some HTML by calling $smarty->display(...). So I presume that in any file where the $smarty object is present this object has a variable called is_admin. However, it doesn't seem to be the case.
Additionally, "normal" Smarty warnings about unset variables look differently:
PHP Notice: Undefined index: sent_id in /var/www/smarty_dir/templates_c/a5aab2c66c44442365a39981ba9be18e0a1f11ad.file.history.tpl.cache.php on line 123
Any ideas?
Upd.
I've read some logs and I see that such warnings seemingly arise when a user enters a page and gets 302 HTTP status. This may be due to the following code (which is placed after smarty constructor call but before the variables are assigned:
//cookie check
if (!is_logged() && isset($_COOKIE['auth'])) {
if ($user_id = check_auth_cookie()) {
if (user_login('', '', $user_id, $_COOKIE['auth'])) {
header("Location:".$_SERVER['REQUEST_URI']);
return;
}
}
}
So I guess I should move $smarty initialisation after this block and it is likely to help. Still I'm curious about how it relates to the issue.
I think I got it. The issue is really in the piece of code including
header("Location:".$_SERVER['REQUEST_URI']);
return;
My error is that return does not act like exit in this case, because when you call return from a file which is required or incuded into another one, you just return the control to that another file. I wasn't aware of this feature.
'is_admin', is_admin() you are trying to assign the function is_admin() as a variable {$is_admin} to the Smarty template, which according to me, is impossible.
Assign the return result to a variable i.e.:
$var = is_admin();
$smarty->assign('is_admin', $var);
Related
OK most the answers on S.O. are BACKWARDS from what I am having an issue with. My variable is not seen FROM the included file. I have never ran into this, and it is messing everything up. I was using smarty, but since it cant see the var, I went back to old fashion php templating, and still cannot see the var.. here is the scripts in question (a gaming site ofc).
INCLUDED FILE: prep_feature_game.php
foreach($games->gamexml->game as $game){
$d = parseDate($game['releasedate']);
$game['date_month'] = $d['month'];
$game['date_day'] = $d['day'];
$game['date_year'] = $d['year'];
$game['image_60x40'] = showImage($game['foldername'],'60x40');
$game['genrelist'] = displayGenreList($game['gameid']);
//debugPrint($game);die();
$game_list[] = $game;
}
CONTROL PAGE:
switch ($page) {
default:
include('includes/prep_feature_game.php');
// NOTE $GAME_LIST HAS THE ARRAY ^
display('feature_game');
break;
AND THE DISPLAY FILE: FEATURE_GAME.PHP
<h1><?=SITE_NAME;?>'s Featured Games!</h1>
<table>
<?PHP
// TEST FOR $GAME_LIST
foreach($game_list as $field=>$data){
echo $data['gamename'];
}
/*
this produces the error:
Notice: Undefined variable: game_list in C:\xampp\htdocs\ix2\themes\missingpiece\feature_game.php on line 7
*/
}// end switch page
I have many variations over the years of these templates, and the "included" files have never produced this kind of error. I know that included files act as though the script contained is inserted where the include is at.
why is the receiving script unable to see the variable produced from the included script. These are all included, so it should not be an issue
PS
I noticed this started happening when I upgraded from php v5 - php v7, doubt it has anything to do with that, I havent checked that yet since include files are pretty standard.
Your question is not showing the definition of the display function, but unless you declare $game_list as a global within that function it is out of scope. If you include the template it'll work.
include('includes/prep_feature_game.php');
include('feature_game.php');
Or add parameters to your display function.
display('feature_game', $game_list);
Or if you're using smarty you must assign the variable first.
$smarty->assign('game_list', $game_list);
$smarty->display('feature_game.tpl');
First of all a little bit of background on my setup:
I have a local domain name set up, projects.lumesse.com.
PHP version is 5.4.16 running on IIS 7.
Testing in Chrome (latest stable build).
The problem is as follows:
I have a function called 'getVariable' as follows:
function getVariable($name, $default = "") {
if(isset($_POST[$name])) return $_POST[$name];
if(isset($_GET[$name])) return $_GET[$name];
if(isset($_SESSION[$name])) return $_SESSION[$name];
return $default;
}
Going through this function line by line it returns the post variable if it exists, followed by the get variable, followed by the session variable followed by the default (if none of the others exist).
In another include, which is included directly after the functions include, I have the following line:
$_SESSION["Language"] = getVariable("Language", "FR");
This works fine if I put ?Language=DE - the site displays in German as expected. However from the line above I'd expect that the language is persisted if I strip off the querystring.
The first time this page is hit, with ?Language=DE, it should return the get variable. The line above then sets the session variable. Any calls to this function after this would therefore return the session variable, right?
It is actually returning FR, the default, in the case that no language parameter exists, even if I've set the language beforehand.
Any ideas on what I'm missing would be much appreciated.
Found the answer - I'm used to coding in classic ASP and .net which don't need a line to initialise the session. Solution was to put session_start() in the main includes file.
I am trying to call a function from another function. I get an error:
Fatal error: Call to undefined function getInitialInformation()
in controller.php on line 24
controller.php file:
require_once("model/model.php");
function intake() {
$info = getInitialInformation($id); //line 24
}
model/model.php
function getInitialInformation($id) {
return $GLOBALS['em']->find('InitialInformation', $id);
}
Things already tried:
Verified that the require_once works, and the file exists in the specified location.
Verified that the function exists in the file.
I am not able to figure this out. Am I missing something here?
How to reproduce the error, and how to fix it:
Put this code in a file called p.php:
<?php
class yoyo{
function salt(){
}
function pepper(){
salt();
}
}
$y = new yoyo();
$y->pepper();
?>
Run it like this:
php p.php
We get error:
PHP Fatal error: Call to undefined function salt() in
/home/el/foo/p.php on line 6
Solution: use $this->salt(); instead of salt();
So do it like this instead:
<?php
class yoyo{
function salt(){
}
function pepper(){
$this->salt();
}
}
$y = new yoyo();
$y->pepper();
?>
If someone could post a link to why $this has to be used before PHP functions within classes, yeah, that would be great.
This was a developer mistake - a misplaced ending brace, which made the above function a nested function.
I see a lot of questions related to the undefined function error in SO. Let me note down this as an answer, in case someone else have the same issue with function scope.
Things I tried to troubleshoot first:
Searched for the php file with the function definition in it. Verified that the file exists.
Verified that the require (or include) statement for the above file exists in the page. Also, verified the absolute path in the require/include is correct.
Verified that the filename is spelled correctly in the require statement.
Echoed a word in the included file, to see if it has been properly included.
Defined a separate function at the end of file, and called it. It worked too.
It was difficult to trace the braces, since the functions were very long - problem with legacy systems. Further steps to troubleshoot were this:
I already defined a simple print function at the end of included file. I moved it to just above the "undefined function". That made it undefined too.
Identified this as some scope issue.
Used the Netbeans collapse (code fold) feature to check the function just above this one. So, the 1000 lines function above just collapsed along with this one, making this a nested function.
Once the problem identified, cut-pasted the function to the end of file, which solved the issue.
Many times the problem comes because php does not support short open tags in php.ini file, i.e:
<?
phpinfo();
?>
You must use:
<?php
phpinfo();
?>
Your function is probably in a different namespace than the one you're calling it from.
http://php.net/manual/en/language.namespaces.basics.php
I happened that problem on a virtual server, when everything worked correctly on other hosting.
After several modifications I realized that I include or require_one works on all calls except in a file.
The problem of this file was the code < ?php ? > At the beginning and end of the text.
It was a script that was only < ?, and in that version of apache that was running did not work
This is obviously not the case in this Q,
but since I got here following the same error message I though I would add what was wrong with my code and maybe it will help some one else:
I was porting code from JS to PHP and ended up having a class with some public method.
The code that was calling the class (being code that originated from JS) looked something like:
$myObject.method(...)
this is wrong because in PHP it should look like this:
$myObject->method(...)
and it also resulted with "PHP Call to undefined function".
change to use -> and the problem was solved.
Presently I am working on web services where my function is defined and it was throwing an error undefined function.I just added this in autoload.php in codeigniter
$autoload['helper'] = array('common','security','url');
common is the name of my controller.
Please check that you have <?PHP at the top of your code. If you forget it, this error will appear.
First, here are the hierarchy of files:
system/
...index.php
...core/
.......MasterView.php
.......Test.php
...sources/
.......ajax/
............ajaxtest.php
.......js/
............jstest.js
and so on.
index.php includes Test.php.
Test.php contains these lines:
$GLOBALS['foo'] = 'foo'; // note 1
require(ROOT.'/core/MasterView.php'); // render master view.
MasterView.php contains simple html tags but calls on jstest.js in system/sources/js/ directory.
jstest.js in system/sources/js/ directory made an ajax call to ajaxtest.php.
ajaxtest.php in system/sources/ajax/ directory contains this line:
echo $GLOBALS['foo']; // note 2
After running index.php on browser, the following error occurs:
Undefined index: foo in ...ajax\ajaxtest.php ...
particularly pointing to note 2 line. My question is, why does php does not recognize foo index when I have defined it on note 1 line before calling MasterView.php?
PS: I know the above method is not the best way to do it but I only give it as an illustration to my problem.
EDIT:
I've tried using $_SESSION['foo'] instead of $GLOBALS['foo'] in both files just to mention one solution I've tried. Same error occurs. Php does not recognize the index foo.
jstest.js in system/sources/js/ directory made an ajax call to ajaxtest.php.
Global variables are global to the same request only. If you connect files with an AJAX request in between, the global variable is not available because AJAX will create a new request.
You can share data across multiple requests by creating some sort of Server Session State by using cookies, a database or PHP sessionsĀDocs.
I'm new to PHP so I apologize if this is a simple problem...
I am moving a PHP site from one server to another. The new server is IIS 7.0, PHP 5.2.1, with short open tag turned "On", and I don't know how the original server was set-up (I was just given the code).
The following is the very first section of code on one of the pages:
<?
ob_start();
session_start();
if($_GET['confirm'] == 13 || $_GET['confirm'] == 14 || $_GET['confirm'] == 15 || $_GET['confirm'] == 16)
{
include("test/query/test_query.php");
}
?>
When this page executes, the following error is always shown:
PHP Notice: Undefined index: confirm in [file location].php on line 6
Also, users access this page by being redirected from the home page (which is a standard HTML page). The full URL when properly navigated to is the following:
http://www.[site].com/test.php#login
... I understand why the error is thrown. What I don't understand is how this code could ever work as it does on the original server. Could I be missing a configuration setting?
*This same issue happens in dozens of locations all over the site. This is just one specific occurrence of the issue.
The new server has error_reporting set to E_ALL. What you're seeing is a notice, not an error. Try:
error_reporting(E_ALL ^ E_NOTICE)
With error reporting set to E_ALL, accessing a member of an array which is not set generates an error. If you don't wish to lower your error reporting level, before checking $_GET['var'], change your code to:
if(isset($_GET['confirm']) && ($_GET['confirm'] == 13 || $_GET['confirm'] == 14 || $_GET['confirm'] == 15 || $_GET['confirm'] == 16)) {
by adding the call to isset() before you actually access $_GET['confirm'], you will verify that you're not accessing an array member which is not set. ($_GET['confirm'] will only be set if the URL ends in ?confirm=... or ?something...&confirm=...)
I suggest to optimize the code for reading:
if (isset($_GET['confirm']) && ($_GET['confirm'] >= 13 && $_GET['confirm'] <= 16))
And I totally agree with Josh's proposal.
Since there is no index $_GET['confirm'], PHP throws a notice that you are looking at an undefined index. The notice is being displayed because the new server has the E_NOTICE flag set in error_reporting somewhere, either in php.ini or in some config file or bootstrap that is run on pageloads.
From the php manual, E_NOTICE: "Run-time notices. Indicate that the script encountered something that could indicate an error, but could also happen in the normal course of running a script."
You can either try turning off the notices if you aren't worried about them, or use them to track down places where there may be problems.
For the code you posted, an easy fix would be to change the conditional to
if(isset($_GET['confirm']) && <list of OR conditions>)
That way PHP bails out of evaluating the conditional if there is no 'confirm' index.
isset() is a useful function. It returns "true" if the variable exists and "false" if not. Usually, people use it in conjunction with a superglobal like $_GET or $_POST to determine whether you're being sent from another page on the site - this allows you to create different actions based on where your user is coming from and what data is tagging along. It also prevents errors in trying to use variables you haven't yet defined, like the OP is getting. So instead of needing to write two different .php files and worrying about sending your user to the wrong one, you can do it all in one page.
Jay,
I'd be careful about your usage of some of these calls. <?php is more likely to work than <? . I've heard session_start() should be the very first thing set to the browser or it can cause header issues. And yes, you need to have a variable declared before you use it - if you're not typing in [file].php?confirm=[some number] as your URL, your page will break unless you amend it to allow for breaks.
That's because confirm query string variable does not seem to be set, you can check it like:
ini_set('display_errors', true);
error_reporting(E_ALL);
var_dump($_GET['confirm']);