1

I have a function that retrieves some data from the database, formats it as HTML and then stores this HTML into a variable, $output. The problem is that $output cannot be echoed on the screen now, only later, after other functions run. Also this data must be retrieved at this stage, not later.

So how can I call this $output variable in another function, after output to the screen has started?

David
  • 176,566
  • 33
  • 178
  • 245
Alex
  • 60,472
  • 154
  • 401
  • 592

7 Answers7

5

You could define $output in the main script, and import it into a function:

function output() 
 {  
   global $output;

This will probably work for your situation at hand. However, it is considered bad practice to use the global variable space with stuff like this, and rightly so. (Believe me, I've done it for years. :)

There are some other approaches that are better for long-term code quality and maintainability.

Global config array

You could either keep one global array for all global settings. Do this somewhere in your main script:

$config = array();
$config["output"] = "<html>.......</htmL>";
$config["user_language"] = "en";
.....

you import the configuration array into the function like so:

function output()
 { global $config;
   echo $config["output"];

Registry pattern

if you want to do some reading, you could use something more advanced like the Registry Pattern. The snippet shown here looks a nice example for a registry. The Zend Framework also has a class for this.

But things like a Registry are really, really advanced, and probably not necessary for you at this point. I would suggest using one central config array. Should the need for something more complex arise, the config array is easy to find and replace.

Context: Are global variables in PHP considered bad practice?

Community
  • 1
  • 1
Pekka
  • 418,526
  • 129
  • 929
  • 1,058
  • All the OP has to do is return `$output`. Then he can do with it whatever he wants. Even with all the warnings about global being bad, the solution above still suggests to use the global keyword to solve the issue. Using a Registry pattern is somewhat better, but basically it's not much different from using the global keyword. It's just less litter in the global scope due to the data confinement within the Registry – Gordon Jul 01 '10 at 17:00
  • @Gordon yes, but the OP's question sounds like the database operation must take place before any output - possibly to do a redirect in case of an error. In that case, he will need a place to store the result in somewhere. – Pekka Jul 01 '10 at 17:53
  • I don't see why. The content is stored in the variable. If he returns it from the function, he can assign it to a variable in the global scope and can do whatever he wants with it: pass around, modify or output. And he can do anything he feels necessary before doing so. – Gordon Jul 01 '10 at 17:59
  • @Gordon mmm, but he wants to do the outputting in a function as well. Which means he'll have to import it from the global scope. Which is not a problem for a variable or two... but becomes one when the project grows and starts depending on a lot of globals. But, you could be right and a simple returning the best thing. Still, I think it's good to talk about these things early on, just to have mentioned the issues behind them. – Pekka Jul 01 '10 at 18:15
  • I just dont get why he has to import anything at all when he can just inject it: `$db = new Db; $output = createOutputFromDb($db); somethingElseBeforeRendering(); renderOutput($output);` - what am I missing? – Gordon Jul 01 '10 at 20:40
  • @Gordon okay, you have a point. I may have imagined a more complicated situation than it really is, with functions or classes where an injection is not really practical. – Pekka Jul 01 '10 at 22:05
5

welcome to using returns, and passing parameters: DO NOT USE global , it breaks encapsulation, one of the cornerstones of object oriented programming, and can lead to incredibly hard to maintain code.

<?php

function doSomethingInDb(){
 $value = db_result(); //something from the database, this is psuedo code
 return $value
}

function displaySomethingFromDb($input){
 echo($input); //or some other way of displaying
}

//calulate results
$output = doSomethinginDb();

//do other stuff...

//output the result when you need it...
displaySomethingFromDb($output);
Mike Sherov
  • 12,634
  • 7
  • 38
  • 62
3

You have to pass the variable via a function argument, or define it as global inside the function.

$output = '<p>macilaci</p>';

function doesathing($output)
{
echo $output;
}

OR

function doesathing()
{
global $output;

echo $output;
}
Jauzsika
  • 2,881
  • 3
  • 21
  • 32
1

don't put the data in a variable inside the function which retrieves it.

function retrieve(...)
{
    ... fetch from db
    return $rv;
}

function other() {...}
function still($data)
{
    ...
    echo $data;
}

$output = retrieve(...);
other();
still($output);
just somebody
  • 16,800
  • 5
  • 47
  • 58
1

Rather than just putting this snippet into a global variable, IMHO a better solution is to use a templating system to construct the elements of the page.

NB I'm not suggesting you immediately rush out and start downloading Smarty - although there are benefits and drawbacks to completely seperating logic and presentation, there are only benefits in taking a modular approach to your screen layout.

C.

symcbean
  • 45,607
  • 5
  • 49
  • 83
0

Put the following line at the start of the function that defines $output:

global $output;

Put the same line at the start of any function that will make use of it.

(This will not work, or will interfere with other variables, if there is already a variable called $output in the global scope.)

Hammerite
  • 19,804
  • 4
  • 65
  • 82
  • 6
    Not to mention that global variables are usually a bad idea in any case. – Ignacio Vazquez-Abrams Jul 01 '10 at 16:07
  • 3
    Teaching someone to use globals (except the SUPERGLOBALS) in php should be considered a crime. – Mike Sherov Jul 01 '10 at 16:12
  • 1
    -1. patient: "doctor, my foot is itching." doctor: "here's your shotgun." – just somebody Jul 01 '10 at 16:17
  • Apparently, Mike, two people agreed with you strongly enough to vote my answer down! That's pretty pathetic in my view. However you feel about the advisability of using global variables, you cannot deny that my answer provides a straightforward way to do what the OP wishes to do. To whoever voted this down: did you do so because you reckon the proposed steps will not solve the OP's problem, or because you have a religious dislike of global variables? – Hammerite Jul 01 '10 at 16:20
  • 1
    reason for my -1: you may have solved his immediate problem in exchange for many more, more complicated problems. see my itch/shotgun comment. – just somebody Jul 01 '10 at 16:23
  • Would you care to support your assertion that he "may have" obtained more complicated problems with any reasoning whatsoever? Or indicate what those problems are? If your code is well-managed then sparing use of global variables will not cause problems. – Hammerite Jul 01 '10 at 16:26
  • The downvote isn't mine, but after years of using globals this way myself, I have reached the conclusion that using them is indeed a bad practice no matter how small your project. The earlier one explores the better ways of managing global state, the better - it can save one a lot of work later. Being shown better ways of doing something is one of the core principles of SO. – Pekka Jul 01 '10 at 16:38
  • @Hammerite, I did not vote you down, and the tone of my comment was intended to be funny, not mean. Sorry if it make across in the wrong way. To answer the question, the problems with globals is that they are in the global scope. If you work in a team, or even with old code, there is a good chance you are using a variable called $output elsewhere in the code. When it's not what you except because some function you wrote a while ago is secretly modifying it from another scope, it's very hard to debug. – Mike Sherov Jul 01 '10 at 16:39
  • but this is the only disadvantage? possibility of variables having the same name? if yes, it's not that big of a deal in my opinion. you just have to be careful:) – Alex Jul 01 '10 at 16:46
  • @Alex it is bad because it is a dependency on the global scope. If function foo() requires the content of $bar, then pass $bar into foo() through the function call, e.g. foo($bar). That will keep foo() a decoupled and discrete unit of code. Everything foo() needs to do it's work is provided through the function invocation. If foo() has to fetch something from outside itself, it cannot run without the outside anymore - foo() would depend on $bar being somewhere out there. - I didnt downvote you either btw. – Gordon Jul 01 '10 at 16:53
0

Use Session

For example:

session_start();
$query = '...........';
$result = mysql_query($query);
$_SESSION['mysqlResult'] = $result;

Now you can use it from any page at any time by simply calling like this

$myresult = $_SESSION['mysqlResult'];
Starx
  • 72,283
  • 42
  • 174
  • 253