I think this is very simple for many of you, but in the moment I got stuck with this. I have the following part of code:
header.php
include "facebook/autoload.php";
use Facebook\FacebookRedirectLoginHelper;
test.php
include "header.php";
$helper = new FacebookRedirectLoginHelper($redirect_url);
Why do I always get this error:
Fatal error: Class 'FacebookRedirectLoginHelper' not found in test.php on line
I thought when I include a PHP file, classes can also be used. But in this case not, why? I think I do not understand how this autoload and use works, so I would be happy for some explanation.
PHP does not inherit the namespaces nor the use statements of included/required files. This is intentional as otherwise if you include 2 files using a class aliased the same way you will get errors and you might not need all those classes in firs place.
If a class requires a namespace it has to have use statement defined with the full namespace to the particular class they need. Except in the cases where there might be aliasing. For example if you have:
// file1.php
use \My\Cool\LogWriter as Writer;
and
// file2.php
use \My\Cool\FileWriter as Writer;
Now both classes are accessible as Writer.
// test.php
require 'file1.php';
require 'file2.php';
In which case if you don't declare which class from which space you want this will give nasty error that class Writer is defined, which is true, but it is also true that the two classes are 2 separate ones.
For more information on namespaces in PHP5 see (http://php.net/manual/en/language.namespaces.php).
As a side note:
Every file, if not namespace declaration is provided is considered in the global namespace.
If a use is without leading slash the namespace might be considered relative to the current. (unsure but I think it depends on the autoloader?) (Reference here: https://stackoverflow.com/a/4879615/1747193)
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 got a simple question for you hopefully. Can it be possible that I just initialize the namespace for a class once in my "main file" and all other objects or classes got the same reference of it ?
For example Index.php:
require_once 'init.php';
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
and now I got a class not in the same file with this kind of code. Controller.php:
function programmAction($id) {
$programm = $this->model->getProgrammById($id);
$html = $this->renderTemplate($this->tempProgramm,['programm' => $programm]);
return new Response($html);
}
Normally when I don't add the use lines as well to this file I would get an error message that the class Response was not found.
Only if you include all other classes in the same file. Refer to this note from the manual:
Note:
Importing rules are per file basis, meaning included files will NOT inherit the parent file's importing rules.
Please don't include all of your classes in one file.
It may seem like a pain to retype the use statements in each and every class file, but really it will help you when you go back and refer to that file later. Right at the top is a list of classes that your class depends on, and could be helpful information during a refactoring or code reorganization.
I just wanna use a namespace in another file, to use the class in it, but im too retarded to do this...
first file:
namespace fun;
use fun\kjr\trouble;
$trouble = new trouble('http://someURL');
second file:
namespace fun\kjr;
class trouble { ... }
This is the error i get:
Error: Fatal error: Class 'fun\kjr\trouble' not found in D:\wamp\www\fun\index.php on line 8
Where did I declare a wrong namespace? Oo
Greetings
I had to include my class aswell.
use namespace
only makes the class available in the actual context.
It does NOT include it, so you can cause it.
use
include_once('your.file')
to do that!
Thanks #Michael Berkowski for helping.
The problem (from what I can see) is you haven't specified an autoloader (e.g. with spl_autoload_register()) or haven't included the file in your code. The use statement will only find a class for you if you have an autoloader in place, otherwise you must include your code ahead of time with include/include_once or require/require once.
I would start with making an autoloader and registering it and then it may be wise to map your namespaces to directory structure as specified by PSR-0.
I am trying to figure out how to use the namespace in php. I have been reading about how to use it and for some reason I can not get it to work. I have two files one which I have stored in Applications/Database/Classes file name is DatabaseConnection.php and the other in the root directory called DB.phpinside the DatabaseConnection.php file I have the following code:
<?php
function hello()
{
echo "hello";
}
?>
This is the DB.php file contents:
<?php
namespace Applications\Database\Classes;
ini_set('display_errors', true);
hello();
?>
Maybe I am completely missing how to use it properly but if I set a namespace is that the same as using include or require? I might be completely misunderstanding how to use it. I am new to OOP and have never heard of namespaces until I started trying to learn OOP? Can someone point out what I did wrong.
Namespaces are for organizing your code in so that you can divide components up and help with the readability. For example if I have a class Pittbull and another Dashund I can place them into a namespace like so for organization:
Animals.Dogs.Pittbull
Animals.Dogs.Dashund
This also helps with potential collisions like the below:
Animals.Dogs.Misc
Animals.Cats.Misc
The Misc class exists twice in this instance, but instead of there being a conflict of which Misc to use, you can use the same class name for both classes (and have different properties and methods inside of them) and not have a conflict of which one you want to use.
The require keyword is a completely different concept and is used to load actual files into the executing script.
Instruction how to use autoloading in PHP (PSR-0):
https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md