How does Laravel load PHP files - php

The first three lines of database\seeds\DatabaseSeeder.php are:
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder { ... }
The Illuminate\Database\Seeder namespace points to vendor/laravel/framework/src/Illuminate/Database/Seeder.php.
How does Laravel require the files from relatively complex directory structures so easily just by using its namespaces?
Where are the files are actually loaded with require (like: require 'path\to\file';)?

Laravel
Laravel uses PSR-4 autoloading via Composer to load files. Mainly, composer manages how classes and files are loaded.
Custom Framework
Most PHP frameworks today, like Laravel, use spl_autoload_register() to handle the dynamic loading of class files when a class has not been loaded. PSR-4 is a community standard from the PHP-FIG used to describe the format of classes and how their files should be written.
The PHP-FIG has example autoloaders you can modify for your own projects.
Relevant links
http://php.net/manual/en/language.oop5.autoload.php
http://www.php-fig.org/psr/psr-4/
https://getcomposer.org/
https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md

If you open the index.php file you will see there in line 22:
require __DIR__.'/../bootstrap/autoload.php';
This require the autoload.php file, which loads the composer autoloader:
require __DIR__.'/../vendor/autoload.php';
Which handles all the automatic loading of the different files (classes/libraries).

Related

Are PHP Namespaces dependent on path of file?

In YII2 Framework
Path of File is root\vendor\yiisoft\yii2-httpclient\Client.php
Namespace defined in above mentioned file is - namespace yii\httpclient;
Now when I use this namespace in other file while setting up Google ReCaptcha
by writing "use yii\httpclient\Client"
then I am getting error "Class yii\httpclient\Client" not found
So I want to know whether namespaces are path dependent ? or is there a routing file or htaccess..etc where I can define the actual path of namespaces used in project, which YII2 compiler will refer to locate the file / class ?
Namespaces themselves are not dependent on file path.
But you are probably mistaking what use clause does.
If you have this line in file:
use yii\httpclient\Client;
It doesn't mean that the class is loaded. It only tells parser that you mean yii\httpclient\Client every time you use Client class in that file.
PHP has something called autoload to make sure you don't have manually require files for each class you are using. Autoloaders are called every time you are using some class if that class hasn't been loaded yet. When they are called they are given the class name and they check if they know how to load that class.
Now, even if the namespaces itself are not dependent on file path autoloaders usually uses those namespaces to decide where to look for the file containing that class.
And as Nigel Ren mentioned in comment, there exist PSR-4 recommendation how to choose namespace and file structure to make sure that autoloader will know where to look for class.
Yii2 projects usually uses 2 autoloaders.
The Yii's own autoloader and autoloader generated by composer.
Since your question is about class that comes from vendor\yiisoft\yii2-httpclient the autoloader generated by composer.
If you check the composer.json file in that package you can see that it has autoloader section with psr-4 key. That tells composer that when it generates its autoloader it should be set to look for any class from yii\httpclient namespace in src folder of that package.
To make sure the composer's autoloader is working properly you have to go through following steps:
The yiisoft\yii2-httpclient package should be installed by composer.
If you need to regenerate composer's autoloader you can run:
composer dump-autoload
The composer autoloader must be included in your application's entry point (usually /web/index.php or /yii files).
Check if those files have this line:
// in case of /web/index.php
require(__DIR__ . '/../vendor/autoload.php');
//in case of /yii
require(__DIR__ . '/vendor/autoload.php');

how to add a PHP library to TYPO3 extension without namespace?

I'm tyring to implement a custom TYPO3 extension to execute some php code. With my main class "hello world!" ist already working and i understand the use of namespaces.
But now I found a php Library that suits my needs. I pasted the lib folder in the "Classes" folder of my extension. But now I'm getting class not found errors because none of the lib classes have a namespace.
Unfortunately I couldn't find any tutorial/doc on how to add a library to a typo3 extension while dynamically adding a namespace to every class. I tried to override every class with a namespace but somehow this cant be the solution
here is a sample of my Main class that is working but as soon as I try to call "ServiceMailman" i get namespace error, well, because they have none
namespace Htwg\GiMailman;
require_once 'Service/ServiceMailman.php';
class GiMailman{
public function getMailinglists() {
$mm = new ServiceMailman('http://localhost', '', '');
}
}
I'm looking for a way to add a php library to the "Classes" folder without adding a namespace to every library class.
Update:
I installed the library on an externel path and added it to the composer.json in the classmap entry:
"autoload": {
"psr-4": {
"Htwg\\GiMailman\\": "Classes/"
},
"classmap": ["/opt/lampp/lib/php/Services"]
}
and it shows up in the autoload_classmap.php:
// autoload_classmap.php #generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
...
'Services_Mailman' => $baseDir . '/../../../../lib/php/Services/Mailman.php',
'Services_Mailman_Exception' => $baseDir . '/../../../../lib/php/Services/Mailman/Exception.php',
);
But when i try to class the class in my Main php class it still can't be found:
namespace Htwg\GiMailman;
//require_once 'Services/Mailman.php';
class GiMailman{
public function getMailinglists() {
$mm = new \Service_Mailman('http://localhost:8001/3.1', '', 'password');
return "getMailinglists";
}
}
Any PHP classes that do not use namespaces are in the top level namespace. So you can use them like:
$mm = new \ServiceMailman('http://localhost', '', '');
You should not add external libraries to you Classes directory. Classes in this directory are autoloaded with the correct namespace for your extension (Vendor/ExtensionName). As external libraries have a different, or in your case no, namespace, this will cause problems. Usually we put external libraries in Resources/Private/Php/LibraryName. You will then need to require or include the library.
If you're using composer it is however better not to include external libraries inside your extension, but let composer worry about it if possible. That way you don't have to worry about autoloading (so you don't need to require or include any files manually) and any dependencies for the external library are also automatically resolved. Either require the library in your global composer.json or, if you install the extension that requires it through composer, add it to the composer.json of the extension.
If you're running composer there are two ways:
The library is available on https://packagist.org/ => Require it in your composer.json file
The library needs to be copied into e.g. Library/ServiceMailman/. After that you set it into your composer.json in the autoload section "classmap", if no namespaces exists for this library. More: https://getcomposer.org/doc/04-schema.md#classmap (If the library has namespaces, it should be in autoload section "psr-4")
If you're not running composer and want to include it in your TYPO3 extension easily, there is a good tutorial: https://insight.helhum.io/post/148112375750/how-to-use-php-libraries-in-legacy-extensions

Composer PSR-4 for php file

In my project I have a folder lib\custom which contains Web folder and functions.php file. In my functions.php I have some functions which I need to use in another classes and in this file on the first line I have a defined namespace look like this
<?php
namespace Custom;
function abc(){....}
And in Web folder I have some classes with namespace Custom\Web;
In my composer.json file I have defined namespace look like this
"Custom\\":"lib/custom/"
So , now I am using the abc() look like this
use Custom;
$abc = Custom\abc("abc")
but as a response I am getting
Call to undefined function Custom\abc()
How can I solve this problem?
PSR-4 describes a specification for autoloading classes from file paths. It doesn't cover loading functions from files.
Use the files autoloader to load a file with functions on each request automatically. This will make your function available as long as you included the autoloader:
{
"autoload": {
"files": ["lib/custom/functions.php"]
}
}
Since your functions are namespaced you'll need to import them with the use statement or use the fully qualified name.
If your Web folder contains PSR-4 compatible classes, load them as before with the PSR-4 autoloader (you can define multiple autoloaders in your composer.json).

Zend Framework 2 load class PHPGangsta_GoogleAuthenticator

I'm trying to load a class that has an underscore in it in ZF2.
This is the project I want to use: https://github.com/PHPGangsta/GoogleAuthenticator
The folder paths look like this:
/module
/Application
/Service
/MyService.php
/vendor/
/PHPGangsta
/GoogleAuthenticator.php
GoogleAuthenticator.php has a class named PHPGangsta_GoogleAuthenticator which I want to use in MyService.php, without having to require any files.
Also, I cannot change files inside PHPGangsta, because the project is submoduled under git.
Can you help configure zf2 class autoload?
Assuming you installed ZF2 using Composer (which is the recommended method), edit your composer.json to add phpgangsta/googleauthenticator to the require section. Then run composer install. That's it. You should then be able to use the library in your application - you don't need to do any additional autoload configuration.

Cakephp 3 loading vendor files

In cakephp 2 when I need a vendor or related class to be loaded globally, i was adding require or app use inside bootstrap.php ot core php.
In cakephp 3 where should I require vendor files ? I dont want to declare vendor require in every class and template file that I use my vendor files.
http://book.cakephp.org/3.0/en/core-libraries/app.html#loading-vendor-files
Vendor files are 3rdparty files. You custom static utility classes are not vendor files but rather your app files. You can put them under src/Lib/. Just ensure to use proper namespace for the classes and add proper use statement wherever you need to use your class.
For e.g. if your lib class is src/Lib/FooBar.php then it should have classname App\Lib and the "use" statement would be use App\Lib\FooBar.

Categories