3

I've been searching and testing different approaches to fix my issue but I still can't find the damn solution. I'm new to PHP and i'm trying to teach myself working with PDO.

db.php:

<?php

$dsn = 'mysql:myHost=localhost;dbname=ewt';
$user= 'root';
$pass = '';

try {
    $pdo = new PDO($dsn, $user, $pass);
    $pdo ->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}

showCust.php

<?php

include_once('db.php');

try {


    $sql = "SELECT * FROM PERSOON";
    $result = $pdo->query($sql);
    while($row = $result->fetch(PDO::FETCH_ASSOC)) {
        echo $row['VOORNAAM']. ' - '. $row['NAAM']. ' - '. $row['EMAIL']. ' - '. $row['ADRES']. '<br />';
    }
    $pdo = null;
}
catch(PDOException $e) {
    echo $e->getMessage();
}

It works perfecty when I copy the db.php code in the showCust.php but I want to split the DB connection from every other file. I know it has to do something with the scope of $pdo but I just can't figure it out ...

The error i keep getting are:

Notice: Undefined variable: pdo ... line 9

Fatal error: Call to a member function query() on a non-object in ... line 9

I know the database does NOT have a pw. This is purely for test purposes.

Thanks in advance !

Community
  • 1
  • 1
user3511568
  • 47
  • 1
  • 7
  • Kudos on starting with PDO! :) Is your connection successful? You are handling PDO object instantiation - I assume you are not getting a 'Connection failed' error? Unless... Are namespacing your code? – Darragh Enright Apr 10 '14 at 14:27
  • Thanks :D ! I actually started yesterday with mysqli but I've read PDO is much better so i'll convert that code later today to PDO! I'm not getting ANY errors when i combine both files in one. I get all the data from the database. But once I seperate them all hell breaks loose :p – user3511568 Apr 10 '14 at 14:30
  • Don't get confused by PDO. An object is nothing but a good old PHP variable, no matter the class. Regular scope rules apply. – Álvaro González Apr 10 '14 at 14:31
  • So it has to do with the try catch I guess? – user3511568 Apr 10 '14 at 14:33
  • @Daan in the db.php i assume ? – user3511568 Apr 10 '14 at 14:33
  • 1
    It's not `mysql:myHost` but `mysql:host=localhost` @user3511568 that's the problem. – Funk Forty Niner Apr 10 '14 at 14:34
  • @Fred-ii- I'll try that. It works though when I combine the files :( – user3511568 Apr 10 '14 at 14:35
  • Of course try/catch does not have its own scope! [Counter-example](http://3v4l.org/7JL1D) – Álvaro González Apr 10 '14 at 14:37
  • I'm sure it will kick into gear @user3511568 When I used `myHost` in my PDO, it threw an error. – Funk Forty Niner Apr 10 '14 at 14:39
  • Changed it and I still get the same error. Also declared pdo outside the try catch still no luck ! – user3511568 Apr 10 '14 at 14:41
  • Ok, well that's just part of the error. Let me see what I can do to work with what you posted. @user3511568 – Funk Forty Niner Apr 10 '14 at 14:42
  • What happens if you remove the try catch block? – Daan Apr 10 '14 at 14:44
  • @Daan Removed the try catch on both files to test if it had to do with the scope. Still same error – user3511568 Apr 10 '14 at 14:46
  • Are the files in the same directory? :- – Daan Apr 10 '14 at 14:47
  • @Daan yes same directory. The thing is when i copy the db.php in addCust.php everything works ... With no scope issues or anything. – user3511568 Apr 10 '14 at 14:49
  • 1
    I tested your code with my credentials with no problem. @user3511568 Are you sure you're using those files and where are you using this, on your own localhost machine or a hosted service? Plus, using `mysql:host=localhost` as previously stated. – Funk Forty Niner Apr 10 '14 at 14:51
  • Yes everything works when I put the db config code inside the addCust.php file. I'm using XAMPP on my machine but I doubt it has anything to do with that since all my other stuff works. I forgot to mention i'm using include_once(addCust.php) in another PHP file. I doubt this is a correct way of coding in PHP but still learning :( – user3511568 Apr 10 '14 at 14:57
  • 2
    Does `addCust.php` also contain `include_once('db.php');`? Instead of doing `include_once` use `include` then @user3511568 Sounds like a scope issue at this point for sure. – Funk Forty Niner Apr 10 '14 at 15:00
  • I ment showCust :p Sorry. Kinda frustrated so I typed the wrong file – user3511568 Apr 10 '14 at 15:01
  • To be clear: There's customer.php where i'm using HTML5+bootstrap. I kinda wanted to seperate the actual script where the SELECT happens to get all the customers so somewhere in customer.php i used include_once('showCust.php') (this is where the ACTUAL script happens ). I do realise this might not be the CORRECT way of coding in PHP but it's for a project so i'm trying to do my best – user3511568 Apr 10 '14 at 15:03
  • You should do **one** include that will or can include other files respectively. Using such a structure will allow you more freedom and less pain. @user3511568 – Funk Forty Niner Apr 10 '14 at 15:06
  • I've tried everything so far to get rid of the $pdo error but nothing works so far haha! :p – user3511568 Apr 10 '14 at 15:07
  • 3
    possible duplicate of [Reference: What is variable scope, which variables are accessible from where and what are "undefined variable" errors?](http://stackoverflow.com/questions/16959576/reference-what-is-variable-scope-which-variables-are-accessible-from-where-and) – deceze Apr 10 '14 at 15:15
  • When i combine both files into one it does work. The thing is if $pdo exists in one try catch does it still exist in the other try catch ? This is a bit confusing haha – user3511568 Apr 10 '14 at 15:23
  • 2
    `try..catch` has zero influence on variable scope (see linked dupe above). The only real possibility in the code you show is that the file is not getting included, period. This may be because you've included it before elsewhere and are using `_once` (as Sense explains), or because the file does not exist and `include` is not killing the script because of it. Try `require` instead of `include_once`. The other possibility is that the example you show has nothing to do with your real code and there's an entirely different problem in your real code. – deceze Apr 10 '14 at 15:29
  • This is SO weird. After nearly 2 hours i deleted db.php created another file called pdoDb.php and now everything works with the 2 php files split. This is so .......... ***** ! – user3511568 Apr 10 '14 at 16:15

2 Answers2

1

In essence, *_once functions in PHP are but a dirty trick. A crutch to help unsuspecting programmer to keep their code in order. But nothing goes for free.

This "once" behavior means you are running this function indeed once.
Means if you have included it once already, all the consequent calls will do... n o t h i n g.

Thus, if you used include_once for db.php earlier in the code and it was inside of a function, then $pdo variable remained local for that function, leaving global scope without $pdo variable. While when included next time, db.php weren't executed and thus you have got no $pdo at all.
However, it's just a speculation.

Other reasons could be various typos. Also make sure you are running exactly the same code you posted here. You'll be surprised by it's working flawlessly

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
  • That last sentence is almost, but not quite, meaningful English. – RobP Apr 10 '14 at 14:41
  • yes, I am bad with English. Thank you for your concern. – Your Common Sense Apr 10 '14 at 14:44
  • It's a good guess. The code we've seen cannot be the actual one. (We know that notices are enabled, though.) – Álvaro González Apr 10 '14 at 14:44
  • I've always found your English pretty good, I just can't make out what you are trying to say. If $pdo was down in a function it was local to that function? I'm trying to parse what the "it" antecedents might be as I am sure there's something worth understanding there. – RobP Apr 10 '14 at 14:49
0

I suspect you did something like this:

$pdo = new PDO...;
function foo(){
    $pdo->query(...);
}
foo();

How about this?

$pdo = new PDO...;
function foo(PDO $pdo){
    $pdo->query(...);
}
foo($pdo);

The issue can also happen the other way round:

function foo(){
    $pdo = new PDO...;
}
foo();
$pdo->query(...);

You're probably posting a simplified example here, since the code you've shared should not trigger that notice. I suggest you actually try the simplified snippets outside your project.


You've just confirmed what I said about not being the actual code ;-)

i'm using include_once(addCust.php) in another PHP file. I doubt this is a correct way of coding in PHP but still learning

Make sure the first call to include_once('addCust.php)' does not happen before the first call to include_once('db.php'); and they both take place in global scope. The notice can obviously also happen if you have this:

$pdo->query(...);
$pdo = new PDO...;
Álvaro González
  • 142,137
  • 41
  • 261
  • 360