Why does my include appear above all of the other content? - php

http://tinypic.com/r/2mn0pph/8
This happens when I do
<?php
require('page.inc');
$homepage = new Page();
$homepage->content = include 'project.php';
$homepage->Display();
?>
But if I do this:
<?php
require('page.inc');
$homepage = new Page();
$homepage->content = "Hello, stackoverflow!";
$homepage->Display();
?>
It does what is intend here
http://tinypic.com/r/1214vbt/8
Is there something special I should do to the include statement to get all the content between the lines?

Use output buffering to catch the generated HTML:
<?php
require('page.inc');
$homepage = new Page();
ob_start();
require 'project.php';
$homepage->content = ob_get_clean();
$homepage->Display();
?>
This way, the PHP is executed, but there's no output to the browser. Instead you'll catch the buffered content in $homepage->content.

From the PHP documentation:
The include statement includes and evaluates the specified file.
Include doesn't not return the text it outputs:
Handling Returns: include returns FALSE on failure and raises a warning. Successful includes, unless overridden by the included file, return 1. It is possible to execute a return statement inside an included file in order to terminate processing in that file and return to the script which called it.
This is what you want:
<?php
require('page.inc');
$homepage = new Page();
$homepage->content = file_get_contents('project.html');
$homepage->Display();
?>
From the PHP documentation
file_get_contents() returns the file in a string
As it was mentioned by #lxg:
"I would assume that project.php contains PHP code to be executed. In this case, file_get_contents('project.php'); would be a bad idea."

Related

How can I pass a variable to an interpreted file?

So I have a case were I need to interpret a PHP file and then put it in a variable as a string.
I have this some what common helper function to do this:
function ob ($path) {
ob_start();
include($path);
$string = ob_get_contents();
ob_end_clean();
return $string;
}
Just give it the path and it will give you the string after it has been interpreted. Works great.
However I also need to send it a variable. I tried just appending a GET request string to the path, but it appeared not to work. The function prototype would look like this:
// how would I implement this?
function ob ($path, $variable_to_send) {
}
How should I do this?
Simply use a global variable.
Set it in one file like this:
$GLOBALS['arg'] = 'test';
Access it in another file similarly:
$arg_passed = $GLOBALS['arg'];
If you wanted to architect this a bit more use the registry pattern.
Note this assumes that this is the same HTTP request. If you need persistence across HTTP requests use session variables.
Let the external script is external.php:
<?php
echo $argument;
?>
and the caller scrip is caller.php (on the same folder of external.php):
<?php
function ob ($path, $argument) {
ob_start();
include($path);
$string = ob_get_contents();
ob_end_clean();
return $string;
}
$out = ob("external.php","Ciao");
echo "$out Cade";
?>
The result will be:
Ciao Cade

Can we store echoed text in a variable in PHP?

When I call a function of another class (in a included file), some text is being output with echo. I need to store this in a variable.
Here is the code:
require_once('../restapis/api.php');
class ApiTest
{
public function testapis(){
$api = new Api();
$api->validate_request();
}
}
$obj = new ApiTest();
$obj->testapis();
And I am getting a JSON string echoed in browser:
{"ERRORCODE":"E032","ERRORMESSAGE":"Invalid URL."}
I don't have permission to change anything in the api.php file, that's why I can't change echo to return.
Is there any way I can do this?
You could use output buffering.
ob_start(); // Activate output buffering
$obj->testapis(); // Whatever code whose output you want to capture
$contents = ob_get_contents(); // Store buffered contents
ob_end_clean(); // Deactivate output buffering
After that, $contents will contain the echoed output.

Echo dynamic content in the middle of a page based on various conditions defined in the head

I am trying to dynamically echo some predefined template ('template-file-for-output.php') filled with some data (from the $var array) on a specific place in a number of pages (as an example, the page 'page.php').
Basically my goal is to have a system, in which
I set up the logic (in the 'logic.php' file), the functions needed (in 'functions.php'), the template (in 'template-file-for-output.php')
with which my colleagues can create whatever page (just as in 'page.php' for the sake of the example) they want with their content and their HTML as they wish and only need to include the functions.php and logic.php files at the beginning of their file, and the echo statement to have the dynamic content where they want it to appear.
The problem I'm having is that when I test this example and try to achieve this in 'page.php', I always get the content before the custom HTML from the page. I suppose it has to do with output buffering and this include in the outputContent function, I tried other things but without success.
Here the contents of the files:
logic.php:
$submitOK = false;
if ($submitOK === true) {
/** No errors, output the error free content */
$output = outputContent($var);
} else {
/** Errors, output the content with errors */
$output = outputContent($var, $errors);
}
functions.php:
function outputContent($var, $errors = null)
{
extract($var);
ob_start();
include 'template-file-for-output.php';
$output = ob_get_contents();
ob_get_clean();
return $output;
}
template-file-for-output.php:
<p>Some content with tags and so on, filled in by some values of the $var array.</p>
<p>Example with the $example variable extracted from $var <?php echo $example; ?></p>
<p>Another variable also from $var <?php echo $anotherVariable; ?>
page.php:
<?php
include 'logic.php';
include 'functions.php';
?>
<!DOCTYPE html>
<html>
<head><title>A page of the site</title></head>
<body>
<p>Something interesting (hopefully).</p>
<?php echo $output; ?>
</body>
</html>
Change ob_get_contents to ob_get_clean, ob_get_contents gets the contents of the buffer but leaves it intact. Your Previous code got the buffer assigned it a variable then, flushed the buffer to output.
function outputContent($var, $errors = null)
{
extract($var);
ob_start();
include 'template-file-for-output.php';
$output = ob_get_clean();
return $output;
}
Setting aside the point that there are currently templating systems that have already solved this problem quite effectively ...
I would try not include the template file, but rather read the file with file_get_contents and then echo it out inside the output buffering section.
function outputContent($var, $errors = null)
{
extract($var);
ob_start();
echo file_get_contents('template-file-for-output.php');
$output = ob_get_clean();
return $output;
}

Get calling file name from include()

I want to get the name of the file that includes another file from inside the included file.
I know there is the __FILE__ magic constant, but that doesn't help, since it returns the name of the included file, not the including one.
Is there any way to do this? Or is it impossible due to the way PHP is interpreted?
So this question is pretty old, but I was looking for the answer and after leaving here unsatisfied, I came across $_SERVER['SCRIPT_FILENAME']; Of course this works if the php file doing the including is a web page.
This gives you the full path of the "including file" on the server. eg /var/www/index.php. so if you want just the filename, eg index.php, you will need to use basename() eg
basename($_SERVER['SCRIPT_FILENAME']);
So, if in your index.php you have the following line:
<?php include("./somephp.php"); ?>
and in somephp.php you have
echo "this is the file that included me: " . basename($_SERVER['SCRIPT_FILENAME']);
you will get
this is the file that included me: index.php
output to the browser. This also works if the user is accessing your file without explicitly including the filename in the url, eg www.example.com instead of www.example.com/index.php.
Solution
Knowing that the functions used to include files are include, include_once, require and require_once, also knowing that they are reserved words in PHP, meaning that it will not be possible to declare user functions with the same name, and based on wedgwood's idea of using debug_backtrace you can actually work out from what file the include was called.
What we are going to do is iterate over the backtrace untill we find the most recent call to any of the four include functions, and the the file where it was called. The following code demostrate the technique:
function GetIncludingFile()
{
$file = false;
$backtrace = debug_backtrace();
$include_functions = array('include', 'include_once', 'require', 'require_once');
for ($index = 0; $index < count($backtrace); $index++)
{
$function = $backtrace[$index]['function'];
if (in_array($function, $include_functions))
{
$file = $backtrace[$index]['file'];
break;
}
}
return $file;
}
The above code will return the absolute path of the file where the last include happened, if there hasn't been any include it will return false. Note that the file may has been include from a file that was included from another file, the above function only works for the deepest include.
With a simple modification, you can also get the last included file:
function GetIncludedFile()
{
$file = false;
$backtrace = debug_backtrace();
$include_functions = array('include', 'include_once', 'require', 'require_once');
for ($index = 0; $index < count($backtrace); $index++)
{
$function = $backtrace[$index]['function'];
if (in_array($function, $include_functions))
{
$file = $backtrace[$index - 1]['file'];
break;
}
}
return $file;
}
Observations
Note that __FILE__ is not the included file, but the current file. For example:
file A.php:
<?php
function callme()
{
echo __FILE__;
}
?>
file B.php:
<?php
include('A.php');
callme();
?>
file index.php:
<?php
include('B.php');
?>
In the above example, in the context of the file B.php the included file is B.php (and the including file is index.php) but the output of the function callme is the path of A.php because __FILE__ is in A.php.
Also note that $_SERVER['SCRIPT_FILENAME'] will give the the absolute path to the script requested by the client. If $_SERVER['SCRIPT_FILENAME'] == __FILE__ it means that the current file is the requested one, and therefore there probably hasn't been any includes...
The above method checks if the current file is the requested one, but not if it hasn't been included (below is an example of how the requested file can be included). An actual solution to check if there has not been any inclusions could be to check count(get_included_files()) == 1.
The requested file can be an included file in the following way:
file x.php
<?php
$var = 'something';
include('index.php');
?>
file index.php
<?php
if (!isset($var))
{
include('x.php');
exit;
}
echo 'something';
?>
In the above example, the file index.php will include x.php, then x.php will include index.php back, afterwards index.php outputs "something" and returns control to x.php, x.php returns control to index.php and it reaches exit;
This shows that even if index.php was the requested script, it was also included from another script.
I can't find the easy way to cover this.
But If the including one is really important to you, you could hack it with some global variable and your own include function.
e.g.
<?php
$g_including_files = array();
function my_include($file) {
$bt = debug_backtrace();
global $g_including_files;
$g_including_files[basename($file)] = $bt[0]['file'];
return include($file);
}
May that be helpful for you :)
This is actually just a special case of what PHP templating engines do. Consider having this function:
function ScopedInclude($file, $params = array())
{
extract($params);
include $file;
}
Then A.php can include C.php like this:
<?php
// A.php
ScopedInclude('C.php', array('includerFile' => __FILE__));
Additionally, B.php can include C.php the same way without trouble.
<?php
// B.php
ScopedInclude('C.php', array('includerFile' => __FILE__));
C.php can know its includer by looking in the $params array.
<?php
// C.php
echo $includerFile;

PHP include/require within a function

Is it possible to have return statements inside an included file that is inside a function in PHP?
I am looking to do this as I have lots of functions in separate files and they all have a large chunk of shared code at the top.
As in
function sync() {
include_once file.php;
echo "Test";
}
file.php:
...
return "Something";
At the moment the return something appears to break out of the include_once and not the sync function, is it possible for the included file's return to break out?
Sorry for the slightly odly worked question, hope I made it make sense.
Thanks,
You can return data from included file into calling file via return statement.
include.php
return array("code" => "007", "name => "James Bond");
file.php
$result = include_once "include.php";
var_dump("result);
But you cannot call return $something; and have it as return statement within calling script. return works only within current scope.
EDIT:
I am looking to do this as I have lots
of functions in separate files and
they all have a large chunk of shared
code at the top.
In this case why don't you put this "shared code" into separate functions instead -- that will do the job nicely as one of the purposes of having functions is to reuse your code in different places without writing it again.
return will not work, but you can use the output buffer if you are trying to echo some stuff in your include file and return it somewhere else;
function sync() {
ob_start();
include "file.php";
$output = ob_get_clean();
// now what ever you echoed in the file.php is inside the output variable
return $output;
}
I don't think it works like that. The include does not simply put the code in place, it also evaluates it. So the return means that your 'include' function call will return the value.
see also the part in the manual about this:
Handling Returns: It is possible to
execute a return() statement inside an
included file in order to terminate
processing in that file and return to
the script which called it.
The return statement returns the included file, and does not insert a "return" statement.
The manual has an example (example #5) that shows what 'return' does:
Simplified example:
return.php
<?php
$var = 'PHP';
return $var;
?>
testreturns.php
<?php
$foo = include 'return.php';
echo $foo; // prints 'PHP'
?>
I think you're expecting return to behave more like an exception than a return statement. Take the following code for example:
return.php:
return true;
?>
exception.php:
<?php
throw new exception();
?>
When you execute the following code:
<?php
function testReturn() {
echo 'Executing testReturn()...';
include_once('return.php');
echo 'testReturn() executed normally.';
}
function testException() {
echo 'Executing testException()...';
include_once('exception.php');
echo 'testException() executed normally.';
}
testReturn();
echo "\n\n";
try {
testException();
}
catch (exception $e) {}
?>
...you get the following output as a result:
Executing testReturn()...testReturn() executed normally.
Executing testException()...
If you do use the exception method, make sure to put your function call in a try...catch block - having exceptions flying all over the place is bad for business.
Rock'n'roll like this :
index.php
function foo() {
return (include 'bar.php');
}
print_r(foo());
bar.php
echo "I will call the police";
return array('WAWAWA', 'BABABA');
output
I will call the police
Array
(
[0] => WAWAWA
[1] => BABABA
)
just show me how
like this :
return (include 'bar.php');
Have a good day !

Categories