0

I am trying to run a query using database credentials from a config file but I keep getting the following error: Uncaught Error: Call to a member function prepare() on null

config.php file:

$host = 'xxxx';
$dbname = 'xxxx';
$username = 'xxxx';
$password = 'xxxx.';   

try {
    $conn = new PDO("mysql:host=$host; dbname=$dbname;", $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    echo "$e->getMessage()";
}

functions.php

session_start();
include 'config.php';

    function getAddress(){
       $output = "";
       if (isset($_SESSION['userid'])){
            $userid = $_SESSION['userid'];
            try {
                $stmt = $conn->prepare('SELECT address FROM users WHERE id = :userid');
                $stmt->bindParam(':userid', $userid);
                $stmt->execute();
                $result = $stmt -> fetch();
                if(empty($result)){
                    $output = "Your information cannot be retrieved";
                } else {
                    $output = $result['address'];
                }       
            } catch (PDOException $e) {
                $output = $e->getMessage();
            }
            $conn = null;
            } else {
            $output = "An error has occured, please try again";
            }
        return $output;
    }

index.php (html page)

<?php 
session_start();
include 'functions.php';
?>
...
<p><?php echo getAddress();?></p>
...

So my index page runs a function (getAddress()) from the functions.php script which connects to a db using credentials stored in config.php.

M9A
  • 3,168
  • 14
  • 51
  • 79
  • 1
    You have to pass the connection to the function. – Jay Blanchard Jul 06 '17 at 19:40
  • Possible duplicate of [Call to a member function prepare() on null](https://stackoverflow.com/questions/35959311/call-to-a-member-function-prepare-on-null) – Sloan Thrasher Jul 06 '17 at 19:42
  • @JayBlanchard how would you suggest I do this? – M9A Jul 06 '17 at 19:45
  • 1
    `echo getAddress($conn);` and change the function call to `function getAddress($conn)` – Jay Blanchard Jul 06 '17 at 19:46
  • Could just declare the $conn as global in the function. Better to pass as a parameter as already suggested though - IMHO. – Nigel Ren Jul 06 '17 at 19:48
  • @JayBlanchard it works! Thanks. Just for educational purposes, why do I need to pass $conn to the function when the function has access to the $conn variable in the config.php file? – M9A Jul 06 '17 at 19:50
  • 1
    It *doesn't* have access, that's the point. `$conn` in the scope of the function has no access to `$conn` outside of the function. In this case `$conn` inside the function is only a convenient name for what we passed into the function. – Jay Blanchard Jul 06 '17 at 19:50
  • 1
    @JayBlanchard Blimey you're right, those programming lessons from years ago are coming back to me. Would there be a better way to acheive this, or is passing the variable through the function sufficient? – M9A Jul 06 '17 at 19:52
  • @JayBlanchard By the way, feel free to submit your suggestion as an answer so that not only can I mark it as the best answer, but others can see it more clearly. – M9A Jul 06 '17 at 19:56
  • Done @Matt9Atkins - glad I could help! – Jay Blanchard Jul 06 '17 at 20:04

2 Answers2

3

Because of the scope of the function call you need to pass in the connection to the function. First, setup the function call to receive the connection:

function getAddress($conn) 

$conn here is just a convenient name for the variable which will use what you have in place inside the function. Passing the connection to the function is the preferred method of making a connection available in a function. The global keyword should be avoided.

Now, call the function with your established connection variable:

echo getAddress($conn);

$conn here is the successful connection from your included file. This will put the connection into the scope of your function and your query should be successful if all else is equal.

Jay Blanchard
  • 34,243
  • 16
  • 77
  • 119
0

try doing

function getAddress()
{
  global $conn;
  // rest of code
}
Norris Oduro
  • 1,019
  • 8
  • 17
  • @JayBlanchard Yes! i agree. i think passing the `$conn` variable as a function parameter would be the best way to go about it – Norris Oduro Jul 06 '17 at 20:09