PDO class could not be found in PhpStorm - php

So, here is some code that I have in my project. Recently started to use PDO methods for connecting to database etc. The problem is that the IDE that I am using (PhpStorm) can't for some reason find any PDO classes. PhpStorm just shows a yellow line underneath the word and says 'Undefined class PDO'.
The weird thing is that if I put a \ before the word PDO, (ie. \PDO) then the class can now be found. I know that from doing some research that you can include it like so use \PDO, however I don't really want to have to do that.
Lastly, wanted to mention that in external libs within PhpStorm that PDO is included which is even more confusing but hopefully you guys would be able to help me out with this.
EDIT - Answer
Ok, after some help I was able to find out why I was getting this issue. At the top of this file I had namespace App\DB; because of this Php was not able to find the PDO class. So, actually putting a \ in front is actually the correct way to do it.
Big thanks to IMSoP, tete0148, Jim Wright.

Just add a backslash before class names because PHP standard classes are located in the root namespace.
\PDO
\PDOException
Or add a use statement at the top of your file.
use \PDO;
use \PDOException;
Note that PHPStorm can automatically import classes by pressing alt+enter while the cursor is over a warning.

I think you have jumped to the conclusion that PHPStorm is telling you the wrong thing, but actually you need to learn how namespaces in PHP work.
Adding a leading backslash to a class name is a way to reference its absolute namespace path.
In this case, the PDO classes are in the root namespace, so they are just \PDO etc; if they were in a namespace called Acme\Widgets, you would write \Acme\Widgets\PDO as the fully-qualified class name.
Fully qualifying the name like this is necessary if the file you are writing is itself declaring code in a particular namespace; that is, if it has the namespace keyword at the top of the file. In that case, the bare name PDO is assumed to be a class in the same namespace you are writing code in. If your file begins namespace ZOulhadj\DB, then new PDO will be expanded as though you'd written new ZOulhadj\DB\PDO.
If this is the case, it is not just PHPStorm which will not be able to find the class - PHP itself will also fail to find the class. PHPStorm is pointing out an error to you so you can fix it before you run the code.

#yann-chabot's (deleted) answer is correct that it will work if you add \ before the classes but he is not clear on why.
In PHP backslashes are used to determine namespaces, and the PDO class is in the root namespace.
If you are in the same namespace as another class, you do not need to specify the namespace when using it. Otherwise, you should specify the namespace.
A simple way of thinking about namespaces are as folders.
For more info see the PHP manual.

Related

PHP namespace class not found when Use statement is in included fle

My problem seems to be around where I am declaring my classes. If I have everything in one .php file, the autoload, the Use declarations and my script that uses those classes within the same file it all works correctly. However, when I have my "Use" statements in a separate required file, I get class not found errors. I eventually want to instantiate class objects in a function, but I can't get past this issue.
My fault - I needed to have the Use statements at the top of every included file. Right there in the documenation, somehow I missed it.

Modern PHP Book - Clearification about "use" and "require" when using Namespace

I'm currently reading Modern PHP Book and I'm a little confused since in Chapter 2 the author talks about Namespace and he keeps saying import when he refers to the "use". In fact he states the following...
TIP
You should import code with the use keyword at the top
of each PHP file, immediately after the opening <?php tag or...
The way I understand Namespace is that the use keyword references the namespace of the class but it doesn't import it and you still need to use require or include to import the actual class, correct?
I'm I correct when I say that when using namespace without auto-loading you will need to use require or include to import your classes?
Thanks
If you use autoloader, such as composer, you do not need to import or require PHP files (you only load autoloader file, which actually does all that for you). If you have no autoloader, you have to load files using import or require.
Then, after FILE is loaded, you can use use statements to do actual work with name-spaced items, such as classes, interfaces or traits.
Yes, you're correct. The use keyword in PHP merely aliases a namespace, in that it does what a symlink (on a *nix system) or shortcut (on a Windows system) would.
If you read the manual about PHP namespace basics you'll see that namespaces can be analogous to a filesystem where class/interface/constant/function names can be divided up into folders in order to prevent name-clashes.
If you read the manual section on Namespace Importing you'll see that when we refer to importing in PHP it actually means to create a shortcut of one name to another name (in fact the shortcut analogy above is taken right from the manual)...
This is similar to the ability of unix-based filesystems to create symbolic links to a file or to a directory.
So, while confusing, the use keyword in PHP does not attempt to load (or include) the actual file containing the namespace, but rather just creates an alias for given namespace(s).
This may be very different use of the word import than you may be used to in other languages, where import can mean to load the actual file or package, but in PHP it's important to understand that importing a namespace has nothing to do with autoloading or including files. They are two separate concepts in PHP.
Importing a namespace is so that you can refer to \fully\qualified\namespace\MyClass as simply MyClass inside your namespace rather than having to use the FQN every single time (hence the shortcut analogy).
Autoloading, is for including the actual classes in PHP when they get used in code.
So there's a definite disconnect between the two concepts.
Since you mentioned a Chapter 2 in a book, I'm going to assume that you are still learning PHP, yes?
The use of use is to shorten namespaced classes to their root so that if you have some long namespaced class like
org\shared\axel\web\framework\connection\pipeline\impl\StopExecutionException
that needs to be instantiated with
new org\shared\axel\web\framework\connection\pipeline\impl\StopExecutionException();
You can use use to refer only to the root unnamespaced class
use org\shared\axel\web\framework\connection\pipeline\impl\StopExecutionException;
...
throw new StopExecutionException();
Keep in mind that you still need to have the class's code in your script, so you either include/require that manually by using include or require, or register autoloaders (see spl_autoload_register).
What that does is you define how your namespace maps to your source code's directory structure.
What others here refer to as composer is a package manager that includes an autoloader. At this stage, I personally think it's better to put off learning about this until you have a good grasp of the basics.
If you have an autoloader then use can be used to pull a Trait
Trait file
namespace Blah;
Trait Foo {
protected $somevar;
}
Class file
Class Bar {
use \Blah\Foo; // autoloaded
}
Otherwise, use is used to indicate that you want to either load a given class or alias that class as another
Class Foo {
}
use \Foo as Bar;
Class Something extends Bar {
}

Can I put PHP extension classes, functions, etc. in a namespace?

I am writing a PHP extension in C, and I would like to put the classes, functions, and variables I am creating in a namespace. I have not been able to find anything in the extension documentation regarding namespaces. To be clear, I want the equivalent of
namespace MyNamespace{
class MyClass{
}
}
but in a C extension. More specifically, I am looking for a function or macro in the Zend C API that allows me to assign a PHP namespace to a class or function I have written in C. Is this possible?
Putting a class in a namespace is very simple. Where normally you would initialize a class with
zend_class_entry ce;
INIT_CLASS_ENTRY(ce, "MyClass", my_class_methods);
instead write the second line as
INIT_CLASS_ENTRY(ce, "MyNamespace\\MyClass", my_class_methods);
The namespace does not need to be included in the method declarations or in the members of the my_class_methods array to properly match them with the class.
To use Namespaces in PHP extensions, you are basically just putting a prefix in front of the class or function name.
I'm not really a PHP internals developer, so the specifics are not entirely clear to me how this works, unfortunately there is very, very little information online that I could find about this as well (I really put Google through it's paces), and the article below is the best I could find.
However, it seems this article hints at the correct solution, which seems to be, that when you register the function with the Zend engine/PHP internals, you do so like "myNS\\MyFunc" and it should then be accessible from the myNS defined there. I would try out a few different variations with this, and see how far that gets you.
Your best option would be to ask in #php-internals on Freenode (if you can get an invitation) or on the PHP Mailing list.
If you manage to find a solution, the Internet seems to be in need of a good article on how one would accomplish this.
Source http://www.php-cpp.com/documentation/namespaces
A namespace is nothing else than a class or function prefix. If you want your classes or functions to appear in a specific namespace, you simply have to add a prefix to the class or function name....
Update: I've updated my answer to try to be more clear. I'm sorry it took so long, I originally replied from my Phone while I was traveling, with every intention of coming back and responding to your original comment, but I genuinely forgot about it until I got a notification from SO about comments. My apologies.

Does PHP's use statement cause extra work when loading classes?

Code Sample 1
use Outline\Drawing;
$var = new Drawing();
Code Sample 2
$var = new Outline\Drawing();
Question:
Does PHP make hardware work harder (look up more files or do more processing) if I use code in sample 1? I am sure something gets done, even if it is at the level of some code that figures out which use line gets matched up with which class. I want to find out exactly what is happenning.
In short:
What does PHP do when working out the connection between the use of the use statement and a class it is supposed to be for?
Are PSR-0/PSR-4 autoloaders affected in the way they work when it comes to these two code samples?
What does PHP do when working out the connection between the use of the use statement and a class it is supposed to be for?
The use statement doesn't actually load the namespace/class into your file. It simply sets up a list of aliases to refer to the classes in that namespace.
When it encounters a class that hasn't yet been declared, it uses that list of aliases to try to fully qualify the class name (prefix replacement). If it can't find an alias for the class, it'll use the namespace of the current scope to qualify the class name.
Only when the class name is fully qualified, that php will try to autoload the class (calling the various autoloaders that might have been defined).
Are PSR-0/PSR-4 autoloaders affected in the way they work when it comes to these two code samples?
No, autoloaders are not affected in the way they work by the difference in your code samples because php will call the autoloaders exactly the same way with exactly the same parameters.

"use" builtin classes without an alias

I see the following code at the top of one of the PHP files im working on.
use DateTime, DateTimeZone;
Is this code useless or is there something I'm missing?
Developers do this to make their lives a bit easier and the code a bit more pretty when working inside namespaces. To explain a bit...
You use namespaces to prevent possible naming collisions with different frameworks. Let's say you work inside a namespace 'MyApp'. Now, because you are now inside of a namespace, you cannot use php's native classes without the leading '\' because those native classes live in the global namespace ( which you identify with '\' before class names ). So if you ever need to use the native DateTime class, you would have to use it with the backslash - \DateTime.
But you can also import things from other namespaces if you know you are going to use them - by using the use keyword after your namespace declaration. That way, you do not have to use the full namespaced name of a class you are going to use, but only the class name itself as you are used to from working without namespaces.
Saying
namespace MyApp;
use DateTime;
Will import the \DateTime class into your MyApp namespace, effectively allowing you to just use DateTime in your code.
You should read more about namespaces on php's website. There's more stuff to be told about namespaces than I can possibly cover in this post.
Presumably, the file in question is under its own namespace.
It's used so that you don't have to use \DateTime in the code.
This code is because it is likely that the source file will also contain a namespace definition. This means that you can access built-in classes only with a leading \ after that namespace definition:
like:
namespace Foo;
$dt = new \DateTime();
To prevent themselves from typing the leading \ or in order to make it possible to include some legacy code, they aliased the classes

Categories