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.
Related
I have a function which creates a new instance of a form template I've made (not using a template engine) and fills it in with various data based on an object thats passed to it. I use this function to create forms for existing objects when the page is loaded, but I also have a button in the interface which makes an ajax request to a separate script which creates a new object and then calls that function to create a form for the object to be sent as a response to the ajax.
The error is:
Warning: DOMDocument::loadHTMLFile(): I/O warning : failed to load external entity "templates/form_edit_event.html" in C:\wamp64\www\<private>\src\<private>\components\component_edit_event.php on line 12
The code it references:
11 $eventDom = new DOMDocument();
12 $eventDom->loadHTMLFile('templates/form_edit_event.html');
The thing is though, when the page is first loaded, my script and the loadHTMLFile function work just fine to create the forms for the already existing objects. The I/O error only occurs when I use the button to try to make a new one. The exact text of which is as follows, although I obscured some directory names that shouldn't matter:
The files it's loading is pure html, not even a header/footer/etc, just <form>contents</form>. I have no idea why it would fail only sometimes.
The entire script (minus some irrelevent use/includes) being called from ajax is this, with component_edit_event.php being the script mentioned above which creates the form:
include_once __DIR__ . '\..\components\component_edit_event.php';
$tourneyId = $_POST['tourneyId'];
/** #var DimTournament $tourney */
$tourney = DimTournament::findById($tourneyId);
$newEvent = new DimEvent($tourney);
echo createEventForm($newEvent)->saveHTML();
I don't think I should need to include any other code but I absolutely can if needed.
Swapping the relative path in $eventDom->loadHTMLFile('templates/form_edit_event.html'); to an absolute path fixed the issue. The script that was throwing the error was in a different directory from the script which was working fine.
I'll be making a config file with some sort of $srcRoot variable for the sake of keeping some semblance of pseudo-relativity in the path names.
I'm studying a code from CMSimple 3.0 framework, with this line:
if (eregi('login.php', sv('PHP_SELF')))die('Access Denied');
So, it's suppose to display "Access Denied" if the char "login.php" is present in sc('PHP_SELF').
I know that PHP_SELF is the name of the running script (i-e the name of the page being called). But after some research I was not able to find out the role of function sc.
Any idea why?
The documentation for CMSimple tells me:
Returns the server variable $name, if it's set, the empty string otherwise.
The function sv in the version of CMSimple you're working on is defined on line 190 of cmsimple/cms.php (you'll notice that is the only script that does not throw a fatal error when called directly). Although the documented definition is quite brief you'll notice sv does a couple of things:
It creates a global variable array named $_SERVER consisting of the variables in $GLOBALS['HTTP_SERVER_VARS'], unless the array $_SERVER already exists.
The HTTP_SERVER_VARS array contains information such as headers, paths, and script locations. You will find some familiar elements in these arrays, like; PHP_SELF (which is the file name of the current executing script), REMOTE_ADDR, QUERY_STRING, and PHP_AUTH_USER. All variables that you will see sv queries for in this code base.
If/When $_SERVER exists it queries the array for a variable and returns it, unless the variable isn't set; then it returns ''.
The code you posted
if (eregi('login.php', sv('PHP_SELF')))die('Access Denied');
Is comparing the expression 'login.php' to the name of the script that is being executed and exiting with message 'Access Denied' if they match.
I am trying to do the following:
Open a file, say "myfile.json" from a php- let's call it "utils.php"; Use it in other php pages; close it from another php.
I have tried to include "utils.php" in the other files and write in the utils file, but it does not seem to work. I suppose this happens because utils.php is never actually executed, only included, but if I should execute it, how can I do it without having to refresh any page, preferably right when the user gets on the main page? This should not be seen by the user, what he sees should remain the main page.
Thanks in advance, I am quite new to php, and am trying to learn.
When you include a file, you are running all code inside it. The functions and classes will not be evaluated but will be defined for future use. If you open your file as this example:
util.php
<?php
$file_hand = fopen('/tmp/file.txt','r');
You will have a handle if the operation is completed. However, the variable $file_hand is global. If you need to use a function to close it, you will need the following code to do it:
other.php
function close_file(){
global $file_hand;
fclose($file_hand)
}
or you can pass the handle as parameter like:
function close_file($file_hand){
fclose($file_hand)
}
Doesn't matter how you will close the file. You have to make sure the variable you are using is the same created in utils.php. If you close like this:
function close_file(){
fclose($file_hand)
}
The variable you've created in until.php file is different of this one.
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);
I'm calling a file named ajax.php (from my browser for testing)
ajax.php require_once delete.php
delete.php require_once no_direct.php
delete.php starts like this:
$allowed = array('group'=>'admin');
require_once(ASSETS.'/no_direct.php'); //Yes, ASSETS is defined and no_direct is being included.
In no_direct.php I'm trying to:
var_dump($allowed)
and I just keep coming up NULL.
Does this happen because we are running inside ajax.php's require_once function and the scope of $allowed pushes back to the GLOBAL scope not allowing me to access it from no_delete.php?
I was looking here: PHP variable defined in 'parent' file not recognized in 'required' file , just to be diligent.
I'm sure I could solve this with the GLOBAL keyword, but I was hoping for a little clarification. The PHP scope doc didn't seem to answer the question for me.
It wasn't wrapped in another function as thought to be the case.
Is there any chance that you already have called require_once(ASSETS.'/no_direct.php'); before you assigned value to $allowed?
require_once(ASSETS.'/no_direct.php');
...
$allowed = array('group'=>'admin');
require_once(ASSETS.'/no_direct.php');
Script no_direct.php should not output $allowed in this case.
Output will be:
Notice: Undefined variable: allowed in D:\wampserver\www\gim\no_direct.php on line 2
NULL
p.s. there's my path on localhost in wamp for my test file
Does this happen because we are running inside ajax.php's require_once function and the scope of $allowed pushes back to the GLOBAL scope not allowing me to access it from no_delete.php?
Definitely not.
There are NO scope issues regarding includes.
The only scope-dependent issue is user-defined functions.
So, if there are no functions involved, the only cause can be some mistake/mistype - you're editing/including wrong file, or including HTML code it via http or something of the kind. Just double-check.
So my ajax.php file also require_once build.php and config.php
My build.php file require_once no_direct.php as well.
As the function suggests, it will only require no_direct.php ONCE!
So the NULL that I was seeing was coming from build.php's include and not the delete.php's include of no_delete.