0

Ok, PHP is not in my major stack and haven't really gotten deep into it, I just want to get things done so I'll go straight to the code:

<?php require_once('server_helper.php');  ?>
<?php

echo $table_balance; // "balance"

function get_balance($user_id) {
    try {
        $conn = establish_connection();
        echo $table_balance; // ""
        // some more code...
    } catch (Exception $e) {
        print_r($e);
    }
}

Explanation: server_helper.php is one level up and it has $table_balance = 'balance'; in it. The first echo $table_balance; - outside the function works as expected and prints "balance", while the second one - inside the function prints "".

The establish_connection() function is also from the server_helper.php and it's working fine...

I'm including the file with the above code in another file, which handles the route hit, gets the ID and calls get_balance($some_id); The code in get_balance() used to be in that another file, where I've used to include the server_helper.php and it worked like a charm. The reason for moving the code is that I wanted to abstract away the DB communication in a separate layer.

I've tried with include, include_once, require and require_once with no success.

P.S: I know underscore is discouraged but I don't feel comfortable using camelCase in a case-insensitive languages.

1

3 Answers 3

2

Because it's not how variables in php works. It's outside context of function. Check variable scope in php

There are 2 approaches to get this done.

Pass it as a parameter

make your function to accept it as a parameter

function get_balance($user_id, $table_balance) {
    try {
        $conn = establish_connection();
        echo $table_balance; // ""
        // some more code...
    } catch (Exception $e) {
        print_r($e);
    }
}

And when you call function, pass this variable as second parameter e.g

get_balance($some_id, $table_balance);

Note: $table_balance should be accessible where you are calling get_balance. otherwise go for second approach.

OR

Make it global.

As Ed Heal said in this answer

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the answer, I'm accepting yours because it suggests more approaches, even though the first one is not applicable in my situation.
1

Please read up about global

You need to do this:

function get_balance($user_id) {
    global $table_balance;
    try {
        $conn = establish_connection();
        echo $table_balance; // ""
        // some more code...
    } catch (Exception $e) {
        print_r($e);
    }
}

2 Comments

The global seems to be my only reasonable choice in the situation, thanks. But the question remains - why it used to work /and still dose/ in other files where the use case is 100% the same.
edit: Damn, I figured it out.. in the other cases I write my logic directly in the "route file" if I do say so myself, directly in the if ($_SERVER["REQUEST_METHOD"] == "POST") {//...} for example, which is not really a function, but seems like one because of the if's indentation...
1

While Ed Heal already addressed the quick way to fix, using global to deal with variable scope issues is like using duct tape to fix things. It's ugly and it will eventually start becoming very hard to manage because you'll suddenly be dealing with everything in the global scope.

If you can, start moving towards object-oriented programming where you can organize your variables into classes and have all the class methods have access to those variables / properties:

class MyLedger
{
  private $conn;
  private $table_balance;

  public function __construct()
  {
    $this->conn = $this->EstablishConnection();
    $this->table_balance = "\$123.45";
  }

  private function EstablishConnection()
  {
    // Code to establish and return a connection here...
  }

  public function GetBalance($user_id)
  {
    return $this->table_balance;
  }
}

Then you'd use it like so:

$Ledger = new MyLedger();
echo $Ledger->GetBalance();

Obviously there will be differences to make it actually work for your situation, but that gives you an idea of the syntax. It's a much cleaner way to organize code than loading up on tons of functions and getting confused on names and scopes and all that.

1 Comment

Thanks for the nice example. While OOP helps you organise code I think in my case /rather simple backend system with not very much of a logic/ it'd be rather overhead writing all this boilerplate just for the sake of OOP. It's good to know it's possible tho.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.