2

How can I access standard internal classes from within a namespace?

namespace foo;

class Bar{
    public function __construct(){
        $connect = new \PDO('mysql:host='.$host.';dbname='.$name, $user, $pass);
    }
}

I'm getting an error

failed to open stream PDO.php

I have autoloader code that is working for my custom classes. How can I have the autoloader ignore the internal classes?

I am referring to this link and my code is based on that:

http://www.php.net/manual/en/language.namespaces.faq.php#language.namespaces.faq.globalclass

Edit:

So if I put something like this, it seems to work fine. But then what's the point if I can't use it inside my own class? How would I make the parameters dynamic based on class properties?

namespace foo;
$connect = new \PDO('mysql:host='.$host.';dbname='.$name, $user, $pass);
class Bar{
    public function __construct(){
        //$connect = new \PDO('mysql:host='.$host.';dbname='.$name, $user, $pass);
    }
}
Anthony
  • 36,459
  • 25
  • 97
  • 163
DS.
  • 2,846
  • 4
  • 30
  • 35
  • 1
    You don't need to do anything to have the autoloader ignore the instantiation of internal classes. The autoloader is only called if you try to instantiate a class that hasn't been declared yet. Are you sure the pdo extension is enabled? – kunal Oct 29 '13 at 01:03
  • Yes, PDO is instantiated and working perfectly outside of this Bar class. – DS. Oct 29 '13 at 01:14

2 Answers2

1

A couple of suggestions

First would be to include the PDO files directly in your class. Distasteful, I know, but sometimes necessary.

The second option would be the preferred. Create your instance of PDO elsewhere and then pass your instance to the class. It makes for less mess later on if you do this because you'll only create the connection once, instead of several times.

namespace foo;
use PDO;
class Bar{
    /** @var \PDO */
    protected $pdo;

    public function __construct(){
        $this->pdo = new PDO('mysql:host='.$host.';dbname='.$name, $user, $pass);
    }
}
Machavity
  • 30,841
  • 27
  • 92
  • 100
  • The first option is out of question, because as you said correctly, and to say the least, it's distasteful. I'm curious about the second one. Did you check out the link in the question? Looks like PHP supports referring to global/internal classes from within namespaces. So I'm not sure why I should need a workaround. I'm confused. – DS. Oct 29 '13 at 00:34
  • What I'm talking about is [Dependency Injection](http://fabien.potencier.org/article/11/what-is-dependency-injection). If you create your instance outside your class, you can pass the pointer along and you don't guess where it was set up (this is commonly called Bootstrap) – Machavity Oct 29 '13 at 00:59
  • I read through the link you provided. Picked up a few things. Thanks for that! But here in my case, if Bar is the class that decides which database to connect to, which user (privileges) to connect with, then injecting a PDO object is not possible. As the PDO object constructor actually needs to be passed with this information. In which case, my code above is the one that'd be required to execute and hence hit the wall. – DS. Oct 29 '13 at 01:22
  • Ok, that makes more sense. I had a thought that might do the trick. Check out the edit. – Machavity Oct 29 '13 at 01:43
1

I've been abundantly using namespaces with internal PHP classes and the first code above should work fine, and it does (I tried). Chances are your PDO extension is disabled or misconfigured.

Have you checked whether PDO is available? See if the PDO class exists.

echo class_exists('PDO') ? "PDO exists\n" : "No PDO\n";

If not, you'll either have to enable it or recompile PHP with --with-pdo-mysql.

Czar Pino
  • 6,258
  • 6
  • 35
  • 60
  • Do internal classes require the root namespace `\` ? Asking as a curious onlooker still not using namespaces. – Anthony Oct 29 '13 at 02:38
  • When inside another namespace, yes it does. Here is a previous answer to that, http://stackoverflow.com/a/17910005/1349295 – Czar Pino Oct 29 '13 at 02:45
  • Yes, PDO is configured properly. As I said in the comment under the question, PDO works fine when I use it from, say index.php, under the document root, without any namespace or anything. It's when I use Bar to instantiate PDO is when I hit the wall. But I took Machavity's suggestion below and rearranged my code a bit to pass a $pdo object to Bar. The $pdo object was instantiated in whichever class needs to do a database operation and then passed on to Bar to perform the actual DB activities. Not as neat as I thought I could make it, had the original code in my question worked. – DS. Oct 29 '13 at 05:28