Requiring file with variable in URL - php

I'm using require_once to call a script that will echo back HTML for a the footer of each page. I have each page submitting a variable in the URL for the PHP file to retrieve via $_GET, but because it doesn't see a file with the name of the full URL (including variable) it isn't working. Any work arounds here?
ERROR:
Warning: require_once(footer/footer.php?page=homepage) [function.require-once]: failed to open stream: No such file or directory in /home/content/05/10838405/html/index.php on line 434
If I remove the '?page=homepage' it works perfectly.

Just use a variable
$page = 'homepage';
require_once 'footer/footer.php';
Then in our footer.php you can use $page

GET parameters are a part of HTTP URLs – but the local file system of your server does “speak” HTTP.
So footer/footer.php?page=homepage would literally mean a file of that name (which does not exist, and the characters ? and = are “illegal” as parts of a file/directory name in many file systems).
Since you are asking for a workaround – two easy possibilities (in both cases, only requiring the file by it’s actual name, footer/footer.php, of course):
you re-write the code inside that file to use a “normal” variable to decide what it should output – $page. (Although that might lead to problems with the variable scope, if $_GET['page'] is used inside a function in that file.)
In your script that does the including, you set the GET parameter yourself – $_GET['page'] = 'homepage'; before including the file. This is perfectly legal in PHP, from a syntactic standpoint – semantically, one might see that differently; and also it might lead to problems if in other code further down the line that GET parameter gets evaluated as well, and the value homepage is not expected in that context.

require_once is a local include, its not going via a http request so things like query strings won't work.
do something like:
$page = 'homepage';
require 'footer.php'
$page will be available to footer.php
Edit: Beaten like a ginger stepchild
Additional Reading: PHP Manual: Require Once

The reason you are having this problem is because require_once will look for a file called 'footer.php?page=homepage' which doesn't exist on your filesystem. Romainberger's solution is good.

Related

Include php file that includes another php file?

My PhP files contain some long string constants and I'm trying to factor them out. So I created "my_string_constants.php" and used include in header.php. So far that works fine.
Now another file, page.php also requires the string constants and header.php. The scheme below tries to clarify these dependendies.
The string constants now seem available in my header only, not the rest of my page. I tried to resolve this by adding global ... to each string constant in string_constants.php. This resolved the error of "Unknown variable" but my string constants still seem unavailable to most of the page content.
What's the right way to get this working?
UPDATE
The issue's been solved. I should have used define(myString instead of $myString = .... By doing so, I need just one include in header.php and the constants will be available to page.php as well.
Thanks a million, you guys are great.
One thing you would want to do is distinguish a constant from a variable. Especially if other developers end up working on this, they will be confused by your terminology.
For constants, you do not need to declare them as global and they are defined like so:
define('MY_CONSTANT', 'Value');
It seems to me that the constants file is acting as your site wide configuration file, so to me, it makes sense to have that on every page, regardless of whether header is used or not. I would normally create a bootstrap file for this purpose.
bootstrap.php:
<?php
require_once(__DIR__ . '/constants.php');
require_once(__DIR__ . '/database.php');
require_once(__DIR__ . '/session.php');
You get the point, then every accessible page needs to include this bootstrap file and then possibly the header.
page.php:
<?php
require_once(__DIR__ . '/bootstrap/bootstrap.php');
require_once(__DIR__ . '/header.php');
?>
<h1>Page Title</h1>
In header.php, since it requires these constants, you can handle this in two ways, either check that the constants are defined (meaning, bootstrap was included first) or just use another require_once to make sure that file was loaded.
if (!defined('MY_CONSTANT')) exit('Bootstrap failure');
or
require_once(__DIR__ . '/bootstrap/constants.php');
Going to many directories or "files" deep regarding includes can really cause issues later when you are trying to debug. As a rule I try to only go one level deep in regards to including files. I.e. Create a folder called includes and place everything in there. If there is a file that needs multiple variables, functions etc, then include them in the needed pages at that point doing several includes like so:
<?php
include("includes/header.php");
includes("includes/functions.php");
?>
There are also other issues in regards to having multiple includes, like if you have sessions or cookies some LAMP stacks will require you to declare
session_start();
at the top of every page including all included php files that may need access to that session or cookie.
So to answer your question I believe the simplest solution would be to re-organize your site or script.
in the header page ontop u write
include 'header.php';
and in header.php you write
include 'my_string_constants.php';
so in this case the page.php calls the header and in the header the my_string_constants is being called...is this what you mean?

include not working for some reason

In my php code there is a section which needs to be retrieved from another php file.
I tried accomplishing this by:
include "teams.php?id=".$matchid;
and in the teams.php
$matchid = $_GET['id'];
echo "MATCH ID IS ".$matchid;
The problem is when i open teams.php?id=".$matchid directly it displays the match id fine
however the include doesn't work - i checked the source code of the original page - no code is being inserted. Is there a way to do what i want? I need to get php code from another file whilst passing 2 variables onto that file
Problem
The problem is related to what $_GET really contains:
An associative array of variables passed to the current script via the URL parameters. (...)
And you do not pass $matchid to the script through URL... And you should not in this case.
Solution
But there is a way. PHP does not separate global variables among files, so variables available in one file are available also in the one included:
in file no. 1:
// Assume $matchid is defined
include "teams.php";
in file no. 2 (the one included):
// No need to redefine $matchid - it was defined in the first file
echo "MATCH ID IS ".$matchid;
Also make sure you add <?php at the beginning of the file (the closing tag is not required). Otherwise it will be treated as text and not executed.
The problem is that you aren't loading that page in the browser when you call the include function, so the variable you are appending is not being processed as a URL query param. You are really just taking everything inside teams.php and dumping it into the other file (the one including teams.php) at that position.
If you want to effectively pass something into teams.php then just declare a variable before the include.
Check out http://php.net/manual/en/function.include.php and all will become clear.
That's not how include's work. When you include a file, it's code is executed as if it was written in the same file it's being included in. So teams.php will have the variable $matchid when the including file has that variable, no need to pass it in. Also the way you called the include was incorrect. Doing what you did causes php to look for a file in the current directory called 'teams.php?id=0' (replace 0 with the $matchid value). This file does not exist, 'teams.php' exists, not the URI. It is possible to specify a url by prefixing it with 'http://' however the result would work with the code in teams.php as it would expect to be able to read the php source.
You can do like this include "include "teams.php?id={$matchid}"; and
$matchid = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_STRING);
echo "MATCH ID IS {$matchid}";
If You will use this code, you will be safe from Injects too!
I hope you will apreciate this.

If an include() is conditional, will PHP include the file even if the condition is not met?

This has been on my mind for quite some time and I figured I should seek an answer from experts.
I want to know if it is a poor programming technique to funnel all PHP requests through a single file. I have been working on a website and not sure if it will scale with growth because I am not 100% certain of how PHP handles the include() function.
To better explain how I have build my quasi framework here is a snippet of my root .htaccess file:
# > Standard Settings
RewriteEngine On
# Ignore all media requests
RewriteRule ^media/ - [L]
# Funnel all requests into model
RewriteRule ^(.*)$ _model.php [QSA]
So everything except content within the media directory is passed into this single script.
Inside _model.php I have all my input sanitisation, user authentication, session data gets pulled from the database, any global variables (commonly used variables like $longTime, $longIP etc...) are set. Requests are routed via interpreting the $_SERVER["REQUEST_URI"] variable.
Essentially I have a switch() statement which chooses which module to include(). What I don't understand is: when PHP executes, will it execute every single include() regardless of whether or not the case directive is true?
I am concerned that after time I will have a lot of these modules - and if PHP does at runtime include all the modules it will end up occupying too much processing power and RAM...
--
Edit:
I am really just asking if PHP will 'read' all those files that it potentially might have to include. I know that it shouldn't actually execute the code.
If one of my include() is a 2GB file which takes a long time to process, will PHP always read over that file before executing?
--
Edit:
I have found another similar question (I did search a lot before posting this one)
PHP behavior of include/require inside conditional
I think I can close this off.
No, PHP will execute include in the moment the code fragment is reached.
This is quite important, because you can have php include file with code directly. E.g.
File1:
<?php echo "Foo"; ?>
File2:
<?php
echo "Before";
include("File1");
echo "After";
?>
Sometimes your PHP processor won't even know at compiletime which file to include. Imagine something like include("File".mt_rand(1,10));. PHP won't know the filename to include up to the very moment it reaches the include statement.
will PHP include the file even if the condition is not met?
No, include and require statements are interpreted and evaluated in the same way as other PHP statements. PHP does not scan the script for includes prior to executing.
This can be verified with a simple test:
if(false)
{
include('does_not_exist.php');
}
The above produces no error or warnings. If the include was read before execution, you would see a warning like:
Warning: include(does_not_exist.php): failed to open stream: No such file or directory ...
Warning: include(): Failed opening 'does_not_exist.php' for inclusion ...

$GLOBALS being cleared in URL included page

When I include a page using it's full URL (like include 'http://mysite.tld/mypage.php'), I can't use the $GLOBALS in mypage.php, it returns Undefined index error.
But when I include it using it's relative path (like include 'mypage.php'), then it's OK.
The reason why am I using URL instead of relative path is that I want to include $_GET parameters to mypage.php
Is there any logical explanation of this strange behaviour?
Note that both files are on the same server, in the same directory.
Including files with a URL means the code is run as a separate process, which means it runs under a different variable scope. This is as opposed to if you include the file via a relative path, in which case it is pretty much equivalent to cut and pasting the code into the script.
Essentially this means that the only variables available from your starting script are those that you explicitly pass (as you are in this case using the $_GET variables). This includes the $_SESSION variables, since the caller is your own server rather than the client.
This behaviour is noted in the PHP manual's include page:
If the target server interprets the target file as PHP code, variables
may be passed to the included file using a URL request string as used
with HTTP GET. This is not strictly speaking the same thing as
including the file and having it inherit the parent file's variable
scope; the script is actually being run on the remote server and the
result is then being included into the local script.

Using a query-string in require_once in PHP

On one of my pages I have a require_once('../path/to/url/page.php'); which works with no problems. The moment I add a query string require_once('../path/to/url/page.php?var=test'); it won't include the file anymore. It's just blank. Anyone have any ideas of why? Can you not use a query-string in a require?
Thanks,
Ryan
By using require_once('../path/to/url/page.php?var=test');, php will not make a new request to page.php, it will actually search for the file named page.php?var=test and include it, because in unix, you are allowed to have such a filename. If you want to pass a variable to that script, just define it: $var="test" and it will be available for use in that script.
require loads a File (from a file path) to include. It does not request that file through apache (or other webserver), therefore you cannot pass query strings in this way.
If you need to pass data into the file, you can simply define a standard php variable.
Example
<?php $a_variable = "data"; require_once('../path/to/url/page.php'); ?>
Note, the variable must be set before the include/require is called, otherwise it won't be available.
All answes true. But most importantly: since $_GET is a global, it's present' in all included files as well, so there's absolutely no use in passing those parameters with the include.
require only accepts paths it would be pointless to add any request since it doesn't make any
it simple includes the required code into the current one

Categories