This is what I have at hand:
//Person.php
namespace Entity;
class Person{
}
User file:
//User.php
use Entity\Person;
$person = new Person;
Here, it fails if I don't include the Person.php file. If I include it, the everything works fine. Do I absolutely require to include the file even when using namespaces? If at all we need to include/require files, then how can namespaces be effectively used? Also, can we maintain folder structure by nesting namespaces?
The answer to your question is "yes and no".
Indeed the code implementing class Person has to be included, otherwise the class is not defined and cannot be used. Where should the definition come from, when the code is not included? The php interpreter cannot guess the classes implementation. That is the same in all programming languages, by the way.
However there is something called Autoloading in php. It allows to automatically include certain files. The mechanism is based on a mapping of class names to file names. So in the end it boils down to php searching through a folder structure to find a file whos name suggests that it implements a class currently required in the code it executes.
But don't get this wrong: that still means the file has to be included. The only difference is: the including is done automatically, so without you specifying an explicit include or require statement.
Yes, you need to include every file.
A very good example can be found here on effective usage of namespaces.
With PSR-0 autoloading, the namespace has to be the same as the folder in which the class is, file the filename has to be the same as the classname. This gives you very simple and effective autoloading with composer for example.
Related
This is what I have at hand:
//Person.php
namespace Entity;
class Person{
}
User file:
//User.php
use Entity\Person;
$person = new Person;
Here, it fails if I don't include the Person.php file. If I include it, the everything works fine. Do I absolutely require to include the file even when using namespaces? If at all we need to include/require files, then how can namespaces be effectively used? Also, can we maintain folder structure by nesting namespaces?
The answer to your question is "yes and no".
Indeed the code implementing class Person has to be included, otherwise the class is not defined and cannot be used. Where should the definition come from, when the code is not included? The php interpreter cannot guess the classes implementation. That is the same in all programming languages, by the way.
However there is something called Autoloading in php. It allows to automatically include certain files. The mechanism is based on a mapping of class names to file names. So in the end it boils down to php searching through a folder structure to find a file whos name suggests that it implements a class currently required in the code it executes.
But don't get this wrong: that still means the file has to be included. The only difference is: the including is done automatically, so without you specifying an explicit include or require statement.
Yes, you need to include every file.
A very good example can be found here on effective usage of namespaces.
With PSR-0 autoloading, the namespace has to be the same as the folder in which the class is, file the filename has to be the same as the classname. This gives you very simple and effective autoloading with composer for example.
I've been reading a lot of posts on StackOverflow but I'm not really sure I'm using namespaces, autoloading, and aliasing correctly. This is functioning fine, but I'm not sure I'm properly using these concepts. I've listed some reasons why I think this setup is incorrect at the bottom of the post.
Imagine the following directory structure:
\public_html
- index.php
\Classes
\A
- One.php
\B
- Two.php
One.php is structured like:
<?php
namespace Classes\A;
class A { ....
Two.php is structured like:
<?php
namespace Classes\B;
class B { ....
Then, in index.php I do something like:
<?php
use Classes\A\One as One;
use Classes\B\Two as Two;
spl_autoload_register(function ($className) {
...
});
... ?>
So, a couple things that bug me about this:
If I am doing aliasing (the "use" statements) I still need to list out all of the files. Aren't we trying to avoid doing this by using autoload?
If I want to use internal classes, I need to add a line such as "use \mysqli;" into the class that uses this and do things like "new \mysqli()". Seems kind of messy?
If a class extends a class from another namespace (say Two.php extends One.php for example) then I need to include "use \Classes\A\One as One;" in One.php which seems to be what we want to avoid in the first place
You don't have to reference all of your namespaced classes via a use statement. You can use partial namespaces.
use Classes\A;
new A\One();
So you can see if you had another class in the A namespace it could be instantiated with
new A\Three();
There are many things in the global namespace, you don't need to define them with use. You can just call them \mysqli(). Yes it's a bit unsightly but it allows you to make a function called mysqli in your own code without worrying about collisions with globally namespaced functions.
I'm not sure I follow you on this one. You don't need to do a use in the base class which references itself.
Ultimately it kinda seems like you view use almost like include when they are very different, use, in this context, is a convenience thing so you don't have to type out full namespaces every time.
Your Autoloader also doesn't need to know about your namespaces. The autoloader just tells PHP how to load a class. So if it sees a class come in with the name Classes\A\One you can make it look in the directory /Classes/A for a file called One.php and include it. PHP will make sure that the class is allocated in the proper namespace. The autoloader is just a convenience thing to keep you from having to do includes and requires in each of your PHP files.
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 {
}
I am using Vzaar's PHP Library for uploading videos from my website to their server space.
Now point is - in their library there are some PHP files in which more than one class exists and no class with same file name exists in same file.
i.e. have a look at OAuth.php, there is no class with name OAuth in that file.
Question raised in my mind is
When I create any PHP class file, can I create multiple classes in side one file, and later I can use that file in my code or I can use that reusable code in other project as well.
Should creating such files is good practice?
If the class is of 15 to 20 lines long, then should I create a separate file or I should include that in one file only, like OAuth.php.
Please guide with exact reason, if I will get links of wiki where proper explanation is given, then it will be best.
Putting more than one class in one file in general is a bad practice, and in Symfony2 even more because of the way class autoloader works.
When autoloader is looking for Acme\DemoBundle\SomeClass class it expects it will be in Acme\DemoBundle\SomeClass.php file. So in case you have a second class in the same file it won't work.
Check also PSR standards for class autoloading.
Despite I don't like to define more than one class per file I would like to point it out that PSR-4 is not against this practice if the class scope is private.
Quoting Symfony2 coding standards resource (http://symfony.com/doc/current/contributing/code/standards.html)
Define one class per file - this does not apply to private helper
classes that are not intended to be instantiated from the outside and
thus are not concerned by the PSR-0 and PSR-4 autoload standards;
In this other example (Thanks to Xavi Montero) you can see that the class Psr4AutoloaderClassTest has a helper class MockPsr4AutoloaderClass defined in the same file. So in general you should not, but for a "private helper" it's okey.
https://www.php-fig.org/psr/psr-4/examples
I stated implementing object oriented design into my website. I'm using php, and ran into an issue.
As is my tendency, I like to define one class per one file - nothing else. Normally, if I remember correctly, in most languages classes can be called if they're in the same directory without having to be explicitly linked to the main program (I could be wrong, or unique to virtual machines).
Right now, php sends errors when I don't link the class file to the main file. On top of that, a child class won't execute unless I define the link to the parent's class file.
Do I have to explicitly link all of my files together?
Here's some snippets of my code for detail:
<?php
include_once 'VRC_Header2.php';
include_once 'UserService.php'; //Child class file of DB_MySQL.php
include_once 'DB_MySQL.php'; //Parent class
//Without the two links above, this file will not execute
Then the child class:
class UserService extends DB_MySQL
{...
Any help is appreciated.
Yes, in PHP, you have to include all classes you need before you instanciate them.
One method to circumvent this is to use autoloading:
http://php.net/manual/en/language.oop5.autoload.php
Which is used on most PHP Frameworks (e.g. Zend Framework).
You have to include all class files to one another. Otherwise other pages will not understand where the class is present.
You can use namespace concept.
http://php.net/manual/en/language.namespaces.php
But in this you have to include the class files.