Use Require_once() to include database connection variables correctly - php

I'm a php newbie (but long time developer in other languages) and I'm trying some example db connections in "PHP, MySQL, & JavaScript". It shows an example file to include db connection variables (servername, username, password, database, etc.). I have a php file which has a handful of functions I wrote and one of them has a few SQL queries. For whatever reason, calling require_once in that file doesn't output any errors (I have E_ALL config'd) yet those variables in my database php file are null.
I called an echo with all the variables within that function to see what the heck is going on and of course it prints a blank line. What in the world is out of scope? I have to be missing something simple.
Here's an example of what I'm doing
db_login.php
<?php
$db_server = 'localhost';
// ....
?>
functions.php
<?php
require_once('db_login.php');
function myfunction() {
echo "$db_server";
// ...
}
?>
Call me crazy, but shouldn't this be simple enough to work?

PHP doesn't have function scope like Javascript, so you do not have access to the variables in db_login.php inside the functions of functions.php.
There are multiple ways of dealing with this. Due to your probable use of the server name global constants would probably be a good solution, since nothing can change them.
In your case you can do:
<?php
require_once('db_login.php');
// You have access to $db_server here.
// Create a constant.
define("DB_SERVER", $db_server);
function myfunction() {
// Using a constant. Note that there is no "$".
echo DB_SERVER ;
// Constants are interpreted inside double quotes too
echo "\nMy constant is DB_SERVER";
// ...
}
?>
In your case having the server name as a constant is probably appropriate. If you are dealing with something that you want to treat as a true variable, you can pass the variable into the function by value or by reference:
myfunction($variable);
// by value
function myfunction($pass_variable_to_me_by_value)
{
echo $pass_variable_to_me_by_value;
// ...
}
function myfunction(& $pass_variable_to_me_by_reference)
{
echo $pass_variable_to_me_by_reference;
// ...
}
As a note, in your case, using the global keyword or the $GLOBALS array inside a function is essentially the same as passing by reference., but if you are not passing from the global scope they can be very different (in a Class or from another function for example).

The variables you declare in db_login.php are globals. In order to access them in your function, you need to use the $GLOBALS variable, e.g. $GLOBALS['db_server'], or declare them as global inside your function using the global keyword, e.g. global $db_server.

Inside of the function "myfunction" you don't have access to these variable...
See more in: http://php.net/manual/en/language.variables.scope.php

Related

Why do I have access to a variable outside of a function but not within?

I have a bunch of HTML and PHP code and in the template file it works fine but I'm trying to put it in a PHP function and now when I run the page I get the error Undefined variable: variableName
Here's some code:
function testFunction()
{
foreach ($variableName as $variable):
echo 'tasf';
endforeach;
}
Inside that function $variableName cannot be found but if I move it outside the function it can be found just fine. I'm doing this within a symfony php template file if it matters.
Simple issue of variable scope. If that variable is defined outside the function then either you need to pass it there or declare it global
See Manual Here
PHP Variable Scope
$str = 'Hello World';
echo $str; // works fine
function foo($bar){
echo $bar; // passed as function argument. works fine
}
foo($str);
function bar(){
global $str;
echo $str; // passed from global. works fine
}
Function scope means that variables referenced inside a function, must be declared within it, or passed...
function testFunction($variableName)
{
foreach ($variableName as $variable):
echo 'tasf';
endforeach;
}
Here's a link to the PHP manual on Variable Scope.
Under no circumstances should you resort to using global variables. There is always a better way, and doing so is considered poor practice. It makes your code difficult to follow as it means anyone else may have to read all of it in order to understand what's going on.
You need to use the global keyword to make this happen.
global should be used sparingly however, and can have unintended side effects.

PHP use one central variables file inside functions

In PHP, what is the right way forward for the following situation:
I have a 'central' vars.php which contains some parameters like MySQL hostname, user, pass, a $Test variable which indicates if the code is running in a test environment or not, and some other variables which I use throughout my site.
Then I have a functions.php which contains all the functions I could use throughout my site.
In some of these functions, I might need some the variables out of the vars.php file.
What is the right way to make the vars.php available to 'everywhere' in PHP?
Now I am doing it like this:
vars.php:
<?php
if(strstr($_SERVER['HTTP_HOST'],"localhost"))
{
$Test = true;
}
?>
functions.php:
<?php
function DoSomething()
{
include "vars.php";
if($Test)
{
$String = "Test is true!";
}
else
{
$String = "Test is false!";
}
return $String;
}
?>
index.php:
<?php
include "vars.php";
include "functions.php;
$DoSomething = DoSomething();
echo $DoSomething;
?>
While this does work, I have to include the vars.php in each function I define, this doesn't seem like a 'nice' solution to me.
Isn't there a way to define the variables in vars.php directly in the global scope, and be able to use them inside functions directly without having to worry about including them?
Thanks!
The right way would be using constants instead of variables.
You're looking for global variables. If you include the file at the top of your page and then declare each one as a global within your function like this:
include('vars.php');
function whatHost()
{
global $host;
echo $host;
}
it will work. This is very bad practice though, as global state is very bad 95% of the time. PHP has powerful object-oriented features which allow you to encapsulate functionality and state within objects. I suggest you read up on that and learn about more proper ways of storing application configuration. Note that for this particular situation, you could just use constants (:
Use constants. Define all together and always on top of classes/files.
Constants are uniques and we use them as config info or static/const data.
If u are sue DEFINE remember use const as a string not a var, example:
define("BASE_PATH", "C://base/");
$dir = BASE_PATH . "images/dropbox.txt";
http://php.net/manual/en/language.constants.php

PHP Variable Scope Issue

In my code, I use a public load_snippet function of a class when I need to include HTML or PHP snippets. (I do this instead of a direct include_once because the directory structure varies depending on certain variables).
I had some issues with variable scopes, so I've narrowed down the problem to this: let's say I define a variable within my page:
$variable = 'Hello World!";
Then, I need load in a snippet:
$APP->load_snippet("slider");
The snippet renders perfectly, except that PHP gives an undefined variable error if I try to reference $variable in the slider code. If I directly include the php file, it works as expected, so I don't understand why I'm having this problem, since this is the load_snippet function:
public function load_snippet($snippet){
if(file_exists("app/".$this->APP_TYPE."/snippets/".$snippet.".php")){
include "app/".$this->APP_TYPE."/snippets/".$snippet.".php";
}
else{
include 'common/txt/404.txt';
}
}
Any help you can give me is much appreciated.
The file is being included within the context of the load_snippet() function, and therefore has only those variables which exist within that function. One way to modify this is to make your function accept two variables: the filename and an array of values.
public function load_snippet($snippet, $content) {
if (is_array($content)) extract($content);
if (file_exists("app/".$this->APP_TYPE."/snippets/".$snippet.".php")) {
include "app/".$this->APP_TYPE."/snippets/".$snippet.".php";
} else {
include 'common/txt/404.txt';
}
}
Then
$arr = array('variable' => 'Hello world!');
load_snippet('slider', $arr);
I think include inside a function makes no sense to me... I think that you should put in function
global $variable;
Note that include will put the code inside the function(include will be replaced by code) as i know..
The way you are doing it is an ugly one, but you can use global $variable inside the snipped to refer to the variable. However if you include the snipped inside a function or a method, you'll have to make the variables in that function/method global as well
If you need $variable inside of the App::load_snippet() method, it would probably be best to pass it in:
public function load_snippet($snippet, $var='Hello world'){
if(file_exists("app/".$this->APP_TYPE."/snippets/".$snippet.".php")){
include "app/".$this->APP_TYPE."/snippets/".$snippet.".php";
}else{
include 'common/txt/404.txt';
}
}
//do something with $var
}
You can set a default for when $variable hasn't been set. No globals, no out of scope variables.
Instead you can use the constants like define('VARIALABLE','value'). which will be available to you anywhere in your file
You are including inside a class. Which means that the included file has the same variable scope as the line of code which includes it has. TO fix this all you need to do is put
global $variable;
Above the include.

PHP Preserve scope when calling a function

I have a function that includes a file based on the string that gets passed to it i.e. the action variable from the query string. I use this for filtering purposes etc so people can't include files they shouldn't be able to and if the file doesn't exist a default file is loaded instead.
The problem is that when the function runs and includes the file scope, is lost because the include ran inside a function. This becomes a problem because I use a global configuration file, then I use specific configuration files for each module on the site.
The way I'm doing it at the moment is defining the variables I want to be able to use as global and then adding them into the top of the filtering function.
Is there any easier way to do this, i.e. by preserving scope when a function call is made or is there such a thing as PHP macros?
Edit: Would it be better to use extract($_GLOBALS); inside my function call instead?
Edit 2:
For anyone that cared. I realised I was over thinking the problem altogether and that instead of using a function I should just use an include, duh! That way I can keep my scope and have my cake too.
Edit: Okay, I've re-read your question and I think I get what you're talking about now:
you want something like this to work:
// myInclude.php
$x = "abc";
// -----------------------
// myRegularFile.php
function doInclude() {
include 'myInclude.php';
}
$x = "A default value";
doInclude();
echo $x; // should be "abc", but actually prints "A default value"
If you are only changing a couple of variables, and you know ahead of time which variables are going to be defined in the include, declare them as global in the doInclude() function.
Alternatively, if each of your includes could define any number of variables, you could put them all into one array:
// myInclude.php
$includedVars['x'] = "abc";
$includedVars['y'] = "def";
// ------------------
// myRegularFile.php
function doInclude() {
global $includedVars;
include 'myInclude.php';
// perhaps filter out any "unexpected" variables here if you want
}
doInclude();
extract($includedVars);
echo $x; // "abc"
echo $y; // "def"
original answer:
this sort of thing is known as "closures" and are being introduced in PHP 5.3
http://steike.com/code/php-closures/
Would it be better to use extract($_GLOBALS); inside my function call instead?
dear lord, no. if you want to access a global variable from inside a function, just use the global keyword. eg:
$x = "foo";
function wrong() {
echo $x;
}
function right() {
global $x;
echo $x;
}
wrong(); // undefined variable $x
right(); // "foo"
When it comes to configuration options (especially file paths and such) I generally just define them with absolute paths using a define(). Something like:
define('MY_CONFIG_PATH', '/home/jschmoe/myfiles/config.inc.php');
That way they're always globally accessible regardless of scope changes and unless I migrate to a different file structure it's always able to find everything.
If I understand correctly, you have a code along the lines of:
function do_include($foo) {
if (is_valid($foo))
include $foo;
}
do_include(#$_GET['foo']);
One solution (which may or may not be simple, depending on the codebase) is to move the include out in the global scope:
if (is_valid(#$_GET['foo']))
include $_GET['foo'];
Other workarounds exists (like you mentioned: declaring globals, working with the $_GLOBALS array directly, etc), but the advantage of this solution is that you don't have to remember such conventions in all the included files.
Why not return a value from your include and then set the value of the include call to a variable:
config.php
return array(
'foo'=>'bar',
'x'=>23,
'y'=>12
);
script.php
$config = require('config.php');
var_dump($config);
No need to mess up the place with global variables
Is there any easier way to do this, i.e. by preserving scope when a function call is made
You could use:
function doInclude($file, $args = array()) {
extract($args);
include($file);
}
If you don't want to explicitly pass the variables, you could call doInclude with get_defined_vars as argument, eg.:
doInclude('test.template.php', get_defined_vars());
Personally I would prefer to pass an explicit array, rather than use this, but it would work.
You can declare variables within the included file as global, ensuring they have global scope:
//inc.php
global $cfg;
$cfg['foo'] = bar;
//index.php
function get_cfg($cfgFile) {
if (valid_cfg_file($cfgFile)) {
include_once($cfgFile);
}
}
...
get_cfg('inc.php');
echo "cfg[foo]: $cfg[foo]\n";

global variables in php not working as expected

I'm having trouble with global variables in php. I have a $screen var set in one file, which requires another file that calls an initSession() defined in yet another file. The initSession() declares global $screen and then processes $screen further down using the value set in the very first script.
How is this possible?
To make things more confusing, if you try to set $screen again then call the initSession(), it uses the value first used once again. The following code will describe the process. Could someone have a go at explaining this?
$screen = "list1.inc"; // From model.php
require "controller.php"; // From model.php
initSession(); // From controller.php
global $screen; // From Include.Session.inc
echo $screen; // prints "list1.inc" // From anywhere
$screen = "delete1.inc"; // From model2.php
require "controller2.php"
initSession();
global $screen;
echo $screen; // prints "list1.inc"
Update:
If I declare $screen global again just before requiring the second model, $screen is updated properly for the initSession() method. Strange.
Global DOES NOT make the variable global. I know it's tricky :-)
Global says that a local variable will be used as if it was a variable with a higher scope.
E.G :
<?php
$var = "test"; // this is accessible in all the rest of the code, even an included one
function foo2()
{
global $var;
echo $var; // this print "test"
$var = 'test2';
}
global $var; // this is totally useless, unless this file is included inside a class or function
function foo()
{
echo $var; // this print nothing, you are using a local var
$var = 'test3';
}
foo();
foo2();
echo $var; // this will print 'test2'
?>
Note that global vars are rarely a good idea. You can code 99.99999% of the time without them and your code is much easier to maintain if you don't have fuzzy scopes. Avoid global if you can.
global $foo doesn't mean "make this variable global, so that everyone can use it". global $foo means "within the scope of this function, use the global variable $foo".
I am assuming from your example that each time, you are referring to $screen from within a function. If so you will need to use global $screen in each function.
You need to put "global $screen" in every function that references it, not just at the top of each file.
If you have a lot of variables you want to access during a task which uses many functions, consider making a 'context' object to hold the stuff:
//We're doing "foo", and we need importantString and relevantObject to do it
$fooContext = new StdClass(); //StdClass is an empty class
$fooContext->importantString = "a very important string";
$fooContext->relevantObject = new RelevantObject();
doFoo($fooContext);
Now just pass this object as a parameter to all the functions. You won't need global variables, and your function signatures stay clean. It's also easy to later replace the empty StdClass with a class that actually has relevant methods in it.
You must declare a variable as global before define values for it.
The global scope spans included and required files, you don't need to use the global keyword unless using the variable from within a function. You could try using the $GLOBALS array instead.
It is useless till it is in the function or a class. Global means that you can use a variable in any part of program. So if the global is not contained in the function or a class there is no use of using Global

Categories