Forum Moderators: coopster

Message Too Old, No Replies

Using variable from one function in another

Looking for help on using a variable created in a function, in another func

         

adambruzon

12:02 am on Jun 18, 2010 (gmt 0)

10+ Year Member



Hi Guys,

So, I am playing with functions on my latest project and I have got a problem.

I create a function which makes a call to the MySQL database, which then sets variables for the results, then my second function uses one of those variables, however, I get an error saying "Undefined variable".

If I echo the variables in the index.php I get a result, the only problem is trying to use $AID in the second function.

Please help...

functions.php

function UserDetails() {
global $USERID, $USER, $AID;
$USER = $_SESSION[SESSIONUSER];
$getUserDetails = mysql_query("SELECT * FROM `users` WHERE `username` = '$USER'");
while ($userArray = mysql_fetch_assoc($getUserDetails)) {
$USERID = $userArray['id'];
$AID = $userArray['address_id'];
}
}

function MainAddressDetails() {
global $POSTCODE, $noAddressFound;
if ([b]$AID[/b] > 0) {
$getAddressDetails = mysql_query("SELECT * FROM `address` WHERE `id` = '$AID'");
$numberOfAddresses = mysql_num_rows($getAddressDetails);
if ($numberOfAddresses > 0) {
while ($addressArray = mysql_fetch_assoc($getAddressDetails)) {
$POSTCODE = $addressArray['postcode'];
}
} else {
$noAddressFound = "Uh-Oh!";
}
}
}


index.php

<?php
UserDetails();
MainAddressDetails();

echo "<p>User: " . $USER . "</p>";
echo "<p>Postcode: " . $POSTCODE . "</p>";
?>

rocknbil

4:33 am on Jun 18, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Welcome aboard adambruzon,

<?php
include($_SERVER['DOCUMENT_ROOT']."/functions.php");
UserDetails();
MainAddressDetails();
echo "<p>User: " . $USER . "</p>";
echo "<p>Postcode: " . $POSTCODE . "</p>";
?>

Is that what you mean?

Matthew1980

8:55 am on Jun 18, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi there adam_bruzon,

Or if you want to set the var in the second function as a global, then the parser will search the entire scope of your project until a var is found that matches.

This will work equally as well as rocknbils example.

Cheers,
MRb

adambruzon

11:36 am on Jun 18, 2010 (gmt 0)

10+ Year Member



Hi rocknbil,
Thank you for the welcome.
I forgot to add that bit in the example but the functions.php is included. Thank you for you response...

Hi Matthew1980,
That was the ticket, as soon as I specified the variables as global in the function that i wanted to use it in, it worked!

Thank you both - I was getting really frustrated with this one...

So final code blocks are as follows:

functions.php


function UserDetails() {
global $USERID, $USER, $AID;
$USER = $_SESSION[SESSIONUSER];
$getUserDetails = mysql_query("SELECT * FROM `users` WHERE `username` = '$USER'");
while ($userArray = mysql_fetch_assoc($getUserDetails)) {
$USERID = $userArray['id'];
$AID = $userArray['address_id'];
}
}

function MainAddressDetails() {
global $POSTCODE, $noAddressFound, $AID;
if ($AID > 0) {
$getAddressDetails = mysql_query("SELECT * FROM `address` WHERE `id` = '$AID'");
$numberOfAddresses = mysql_num_rows($getAddressDetails);
if ($numberOfAddresses > 0) {
while ($addressArray = mysql_fetch_assoc($getAddressDetails)) {
$POSTCODE = $addressArray['postcode'];
}
} else {
$noAddressFound = "Uh-Oh!";
}
}
}


index.php


<?php
include 'functions.php';

UserDetails();
MainAddressDetails();

echo "<p>User: " . $USER . "</p>";
echo "<p>Postcode: " . $POSTCODE . "</p>";
?>

Matthew1980

1:57 pm on Jun 18, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi there adambruzon,

Glad your sorted out, but as Rocknbill points out, it is always good to define a root path beit in a constant or using a superglobal (like his example).

To get base dir (make sure that you are in the root of your site) do something like:-

define('ROOTPATH', dirname(__FILE__). "/"); //current dir..

this gives you the root path in a constant that you can refer to throughout the scope of your script, I always find it handy anyway,

Cheers,
MRb

adambruzon

2:22 pm on Jun 18, 2010 (gmt 0)

10+ Year Member



Thanks for that, I can see why this is good practice.

Which do you think is faster:

1. Using the superglobal in all includes or...

2. Using the superglobal once, to include my header.php, then defining the ROOTPATH for the rest?

Thanks

rocknbil

5:04 pm on Jun 18, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Which do you think is faster:


Speedwise, I don't think it matters.

But in terms of good practice, you should create a class, or at the very least, return the values from functions rather than using program globals. You want a function to be a stand-alone bit of code you don't have to futz about with once written; a black box, you pass input to it (or no input) and it returns a value. Then you can reuse it and set the program variables to what you need them to be, at any time.

Have a look at this experiment for an example. May contain errors, typed on the fly, but examine the logic.

functions.php

function UserDetails($user) {
// initialize
$userid=$aid=null;
if (! $user) { die("no user passed to user details"); }
// Actually, the above should be changed to validate the $user value too . . .
$getUserDetails = mysql_query("SELECT * FROM `users` WHERE `username` = '$user'");
// only one record - use IF, not WHILE
if ($userArray = mysql_fetch_assoc($getUserDetails)) {
$userid = $userArray['id'];
$aid = $userArray['address_id'];
}
return Array($userid,$aid);
}
//
function MainAddressDetails($aid) {
$postcode=$noAddressFound=null;
if (is_numeric($aid) and ($aid >0)) {
// so . . .no need for > 0 block now . . . and
// NO NEED TO COUNT. :-) for a single record, fieldname is more
// efficient than * Again, use if for one record.
$getAddressDetails = mysql_query("SELECT postcode FROM `address` WHERE `id` = '$aid'");
if ($addressArray = mysql_fetch_assoc($getAddressDetails)) {
$postcode = $addressArray['postcode'];
}
else { $noAddressFound = "Uh-Oh!"; }
}
else { die("No aid passed to address details"); }
return Array($postcode,$noAddressFound);
}


OK? Now look what we can do. :-)

index.php

<?php
include($_SERVER['DOCUMENT_ROOT']."/functions.php");
// See above, validate this too, not just check if set
if (isset($_SESSION[SESSIONUSER])) {
list($USERID,$AID) = UserDetails($_SESSION[SESSIONUSER]);
// since $aid is initialized as null, in UserDetails, we don't need to
// check if isset - simple if is all that's required
if ($AID) {
list($POSTCODE,$MAILERROR) = MainAddressDetails($AID);
if ($MAILERROR) { echo $MAILERROR; }
else {
echo "<p>User: $USER </p>";
echo "<p>Postcode: $POSTCODE </p>";
}
}
else { die("Session user OK, no AID"); }
}
else { die("No session user has been set"); }
//
// OK let's look up another user!
// Of course, validate this input - for example only
//
if (isset($_GET['other_user'])) {
// Note we can use any variables in this scope.
list($newuserid,$newaid) = UserDetails($_GET['other_user']);
if ($newaid) {
list($newcode,$newerr) = MainAddressDetails($newaid);
if ($newerr) { echo $newerr; }
else {
echo "<p>New User: $newuserid </p>";
echo "<p>New Postcode: $newcode </p>";
}
}
else { die("New user input OK, no AID"); }
}
?>


Just something to get your thinking turned toward better use of functions, next up you can learn classes, an even better extension of these concepts.

Matthew1980

8:49 pm on Jun 18, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi all,

Well with regards to speed - I suppose it must be down to uS, but personally, when referencing include() files, I always set a constant (just like I did in the above post) and then refer to it throughout my script.

But WRT Rocknbills last post, I couldn't agree more :), where you find yourself in this position, or need to retype a process, pop it in a function, this makes for better coding & it will open more doors for you in the long run, especially when you transfer to writing classes - doing this method has done exactly that for me, I'm now hooked on classes! (Doesn't mean they always work though ;))

[EDIT:]Good point there Readie, I suppose it's down to preference, and if you are coding the software with memory optimization top of your design spec of course ;)

Cheers,
MRb

[edited by: Matthew1980 at 9:12 pm (utc) on Jun 18, 2010]

Readie

9:05 pm on Jun 18, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



There's no need to define a constant to get the root path:

include $_SERVER['DOCUMENT_ROOT'] . '/path/to/file.php';

Will go from the root directory. A constant just consumes additional memory.

adambruzon

9:51 pm on Jun 18, 2010 (gmt 0)

10+ Year Member



rocknbil - Classes are definitely next on my list of things to learn. Thank you for that code there, I will look at it more carefully and examine the logic to really understand it. :)

Matthew1980 - I have just got hooked on functions, saving so much coding time and file sizes on repeated code. I am sure that I will have as much fun with classes, but all in good time... Thank you. :)

Readie - Thank you for your input, I will stick to the superglobal method rather than defining a constant. :)