How can I reference variables from another included file in PHP? - php

So I'm working on a PHP app and trying to make everything moduler. I have an index.php file that includes other php files. The first file included is settings.php which has my postgres credentials defined so they can be accessed elsewhere. The second file is connect.php that has a function you can pass sql to and it will return $result. The third file has functions that call the sql function and receive $result and parse it. In the third file, I can read the results of the $result however if I try if($result) it breaks and isset/empty have no effect.
Anyone have any ideas on a way to make this work, or is my structure just terrible?
Thanks so much!
Mike

let's say you have the following three files:
inc1.php
<?php
$foo = 'hello';
?>
inc2.php
<?php
echo $foo;
?>
main.php
include('inc1.php');
include('inc2.php');
it should echo "hello". however, passing variables around among files is a bad idea, and can lead to a lot of confusing, hard-to-follow code. If you need to pass variables around, use functions and/or objects so that you can at least see where they are coming from.
beyond that though, it's difficult to tell exactly what your problem is without seeing the code in question.

I would really try to switch to OOP. This makes things a lot of easier. If you just have to deal with classes, their methods and attributes you only have to include the classes and not this choas of functions. So I would recommend, give it a go ...

Related

PHP eval in eval cannot read predifined variables

Before I explain the issue, I know the risks of using eval, but there is no realy other way to do it on how my system is build, and it also is for a personal project only. (its a custom cms which when I publish it makes the physical files for me, I just made it though db so I don't need to upload files when not working remote and it is just easy).
Lets explain my issue, I have a main php file which handles all pages, all pages are stored in the db with code and all and is being executed through eval.
And the system also has a function include_db which basicly does the same as include from php normaly just from the db.
But when I access a variable defined in the first eval (main page) it can not be read out in the included eval from the db.
Weird thing is that functions can be read out though the second eval.
Any way to access variables normaly from the included eval that is being generated in the eval of the main page?
(I think it has to do because those variables are not global and its being executed in a function but I do not know a way to make every variable global :( )
Thanks in advance!
The code that is being evalled on the main page:
$skill = isset($_REQUEST['skill']) && is_string($_REQUEST['skill']) && isValidSkill($_REQUEST['skill']) ? $_REQUEST['skill'] : 'overall';
if(!isset($_REQUEST['player']))
include_db('highscore_overview');
else
include_db('highscore_player');
And inside the include of overview I dump the get_defined_vars() and that doesn't return the $skill I set before the include only the variables that are declared in the main index.php (database and such)
First of all a disclaimer: You should never ever execute code from a database. That is a big security risk. It means that whenever someone is successful in gaining access to your database (using sql-injection for example) is now also capable of executing arbitrary code in php by changing the code in your database. You really should not do that!
If you are using code from the database to implement custom (email-)templates, please consider using a templating-engine for that like twig. Most syntaxes of template-engines are built in a way that you cannot break out of them and execute arbitrary code like you could with raw php code.
That said, i now try to answer the original question (because i cannot stop you doing things you should not do anyways). In terms of variable-scope, eval behaves like a function. If you want the variables defined inside it global, you have to manually make every variable defined inside the eval global.
You can do that by append a code-snippet to every code executed in eval that takes every local (in eval defined) variable and writes it into global scope.
<?php
function include_db() {
# ... get $code from db here ...
# get's executed after code from db, globalizes all variables
$code .= ';foreach (get_defined_vars()) as $newGlobalName) {';
$code .= ' $GLOBALS[$newGlobalName] = $$newGlobalName;';
$code .= '}';
eval($code);
}

using includes in overall php rather then each function

i am very new to php, i am used to writing .net, and i am finding the includes hard to understand and was hoping someone could help me understand how to correctly use an include once in a file, rather than inside each function..
take the following as an example
<?php
include 'test.php';
function test($a)
{
echo $value_from_test_php;
}
?>
the above code does not seem to work... however the below does
<?php
function test($a)
{
include 'test.php'
echo $value_from_test_php;
}
?>
i am having a hard time figuring out how to make an include work for all functions inside a file, rather then including it inside each function, any advice is greatly appreciated!
It's the scope of variable which is troubling you rather than includes, in PHP generally includes are used where there's a common page/markup to be included on each page, such as footer, header, etc
There are 4 types
include
include_once
require
require_once
The only difference is include will throw you an error if something goes wrong and will continue to execute the script where require will halt the further execution
You'll get everything here on includes - PHP Documentation
It all depends what is inside the file that you are include-ing! I would never, ever, suggest using include inside a function (or loop, or pretty much anything with brackets). Remember, the contents of the file being included are literally just "plopped in" place, right where the include statement is. So whatever scope (global, class, function, etc.) you're in when you include, is the scope that its contents will be declared in.
Put full class and function definitions in files, and include them at the top of the files where they are going to be used.
Your issue is not related to includes, but rather variable scope. By default a variable defined outside a function is not available within the function.
It's difficult to suggest the best solution without knowing exactly what it is you're trying to do, but the documentation (linked above) should get you started.
First example is not working because you use variable from global scope, if you want to use it then replace $value_from_test_php to $GLOBALS['my_var_name']

Using require_once inside a method

From what I understand using something like require_once will essentially copy and paste the code from one file into another, as if it was in the first file originally.
Meaning if I was to do something like this it would be valid
foo.php
<?php
require_once("bar.php");
?>
bar.php
<?php
print "Hello World!"
?>
running php foo.php will just output "Hello World!"
Now my question is, if I include require_once inside a method, will the file that is included be loaded when the script is loaded, or only when the method is called?.
And if it is only when the method is called, is there any benefit performance wise. Or would it be the same as if I had kept all the code into one big file.
I'm mainly asking as I've created an API file, which handles a large amount of calls, and I wan't to simplify the file. (I know I can do this just be creating separate classes, but I thought this would be good to know)
(Sorry if this has already been asked, I wasn't sure what to search for)
It will only include when the method is called, but have you looked at autoloading?
1) Only when the method is called.
2) I would imagine there's an intangible benefit to loading on the fly so the PHP interpreter doesn't have to parse extra code if it's not being used.
I usually use the include('bar.php'); i use it for when i use databvase information, i have a file called database.php with login info and when the file loads it calls it right up. I don't need to call up the function. It may not be the most effective and efficient but it works for me. You can also use include_once... include basically does what you want it to, it copies the code essencially..
As others have mentioned, yes, it's included just-in-time.
However, watch out for variable definitions (require()ing from a method will only allow access to local variables in that method's scope).
Keep in mind you can also return values (i.e. strings) from the included file, as well as buffer output with ob_start() etc.

Making Only Specific Functions and Variables Available in PHP

I want to make a programming environment. I will explain it with an example.
One programmer will write that code;
<html>
<head>
<?php definedMetaTags(); ?>
</head>
</body>
Programmer will save this file and then upload to my system. That file will be executed at server side and then they system will turn generated code back.
That definedMetaTags() function will be already written in the system.
An example of Compiler.php:
<?php
require_once("definitionsForProgrammer.php");
include("uploadedfile.php");
?>
My question is that I want to allow that uploadedfile.php only what functions I want. Else, maybe that programmer writes some codes what I want him/her to do. (Deleting files, mysql connection, etc.)
Is there any way to allow a code only specific functions, variables, constans?
If the goal is to allow a user to insert placeholders that will be replaced by some PHP function execution, then there's no need to treat the uploaded file as PHP code:
<html>
<head>
{[definedMetaTags]}
</head>
</body>
Then Compiler.php would look like this:
<?php
require_once("definitionsForProgrammer.php");
$macros = array();
$macros['definedMetaTags'] = definedMetaTags();
$output = file_get_contents("uploadedfile.php");
foreach($macros as $macro=>$value) $output = str_replace("{[$macro]}", $value, $output);
echo $output;
?>
The definedMetaTags() function would need to be reworked so that it returns the tags as a string instead of printing them directly to output.
This method would allow you to define any number of macros without exposing yourself to all the security risks the others here have mentioned.
If you're aiming for security and you want to let them to write functions, then the short answer is: no.
Essentially you're asking for a PHP sandbox which will let you constrain what code can be executed. PHP would have to support this at a fundamental level for it to work. For example, supposing you took the approach of saying "I only allow the user to write a function named 'foo'". Inside that function, though the user can do all kinds of bad things like making system calls, downloading other code and executing it, etc. In order to prevent this you'd need to implement checks at a much lower level in the system.
If you're willing to restrict the scope only to variable definitions then yes you can do it. You can use token_get_all() and token_name() to examine the file to make sure that it doesn't have any code that you don't want in it. For example:
foreach (token_get_all(file_get_contents("uploadedfile.php")) as $token) {
if (is_array($token)) {
echo token_name($token[0]), " ";
} else {
echo $token;
}
}
If you don't like any tokens you see, don't include the file. You could theoretically guard against bad functions this way as well, but it'll require a fair amount of effort to properly parse the file and make sure that they're not doing something bad.
references:
http://www.php.net/manual/en/function.token-get-all.php
http://www.php.net/manual/en/function.token-name.php
http://www.php.net/manual/en/tokens.php
Well, if i'm understanding your question correctly. If you include("uploadedfile.php"); you will acquire everything in it.
What you could do is break your code up into related sections (whether it be via classes or just function definitions in a file) then only include the file/class that you want.
(let me know if that's not what your asking)

How to setup site-wide variables in php?

I want to define something like this in php:
$EL = "\n<br />\n";
and then use that variable as an "endline" marker all over my site, like this:
echo "Blah blah blah{$EL}";
How do I define $EL once (in only 1 file), include it on every page on my site, and not have to reference it using the (strangely backwards) global $EL; statement in every page function?
Most PHP sites should have a file (I call it a header) that you include on every single page of the site. If you put that first line of code in the header file, then include it like this on every page:
include 'header.php';
you won't have to use the global keyword or anything, the second line of code you wrote should work.
Edit: Oh sorry, that won't work inside functions... now I see your problem.
Edit #2: Ok, take my original advice with the header, but use a define() rather than a variable. Those work inside functions after being included.
Sounds like the job of a constant. See the function define().
Do this
define ('el','\n\<\br/>\n');
save it as el.php
then you can include any files you want to use, i.e
echo 'something'.el; // note I just add el at end of line or in front
Hope this help
NOTE please remove the '\' after < br since I had to put it in or it wont show br tag on the answer...
Are you using PHP5? If you define the __autoload() function and use a class with some constants, you can call them where you need them. The only aggravating thing about this is that you have to type something a little longer, like
MyClass::MY_CONST
The benefit is that if you ever decide to change the way that you handle new lines, you only have to change it in one place.
Of course, a possible negative is that you're calling including an extra function (__autoload()), running that function (when you reference the class), which then loads another file (your class file). That might be more overhead than it's worth.
If I may offer a suggestion, it would be avoiding this sort of echoing that requires echoing tags (like <br />). If you could set up something a little more template-esque, you could handle the nl's without having to explicitly type them. So instead of
echo "Blah Blah Blah\n<br />\n";
try:
<?php
if($condition) {
?>
<p>Blah blah blah
<br />
</p>
<?php
}
?>
It just seems to me like calling up classes or including variables within functions as well as out is a lot of work that doesn't need to be done, and, if at all possible, those sorts of situations are best avoided.
#svec yes this will, you just have to include the file inside the function also. This is how most of my software works.
function myFunc()
{
require 'config.php';
//Variables from config are available now.
}
Another option is to use an object with public static properties. I used to use $GLOBALS but most editors don't auto complete $GLOBALS. Also, un-instantiated classes are available everywhere (because you can instatiate everywhere without telling PHP you are going to use the class). Example:
<?php
class SITE {
public static $el;
}
SITE::$el = "\n<br />\n";
function Test() {
echo SITE::$el;
}
Test();
?>
This will output <br />
This is also easier to deal with than costants as you can put any type of value within the property (array, string, int, etc) whereas constants cannot contain arrays.
This was suggested to my by a user on the PhpEd forums.
svec, use a PHP framework. Just any - there's plenty of them out there.
This is the right way to do it. With framework you have single entry
point for your application, so defining site-wide variables is easy and
natural. Also you don't need to care about including header files nor
checking if user is logged in on every page - decent framework will do
it for you.
See:
Zend framework
CakePHP
Symfony
Kohana
Invest some time in learning one of them and it will pay back very soon.
You can use the auto_prepend_file directive to pre parse a file. Add the directive to your configuration, and point it to a file in your include path. In that file add your constants, global variables, functions or whatever you like.
So if your prepend file contains:
<?php
define('FOO', 'badger');
In another Php file you could access the constant:
echo 'this is my '. FOO;
You might consider using a framework to achieve this. Better still you can use
Include 'functions.php';
require('functions');
Doing OOP is another alternative
IIRC a common solution is a plain file that contains your declarations, that you include in every source file, something like 'constants.inc.php'. There you can define a bunch of application-wide variables that are then imported in every file.
Still, you have to provide the include directive in every single source file you use. I even saw some projects using this technique to provide localizations for several languages. I'd prefer the gettext way, but maybe this variant is easier to work with for the average user.
edit For your problem I recomment the use of $GLOBALS[], see Example #2 for details.
If that's still not applicable, I'd try to digg down PHP5 objects and create a static Singleton that provides needed static constants (http://www.developer.com/lang/php/article.php/3345121)
Sessions are going to be your best bet, if the data is user specific, else just use a conifg file.
config.php:
<?php
$EL = "\n<br />\n";
?>
Then on each page add
require 'config.php'
the you will be able to access $EL on that page.

Categories