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.
Related
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');
I am learning to setup PHP package with PSR-4 autoload using composer. I have managed to set up the working package. But I can access the classes in the same directory but cannot access the sub folder classes from main folder class.
adding my src code link here https://github.com/nsatheesh87/PSR-4-PHP-Test
Kernel.php from src directory trying to access the Http->Request.php class but only i can get Class cannot found error. Also I Checked the namespaces
You miss parameter with create Kernel object
https://github.com/nsatheesh87/PSR-4-PHP-Test/blob/master/src/app.php#L14
This constructor require object of Request class
https://github.com/nsatheesh87/PSR-4-PHP-Test/blob/master/src/Kernel.php#L11
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).
I'm kind of confused on how to load my own code (classes or just regular functions) into a Laravel app. I've seen this done in several ways:
Creating a folder inside the app directory (for example: app/libs) and add app_path().'/libs' to start/global.php
Add it into composer.json's "require"
Add "psr-0" into composer.json's "autoload" and add there the files
Add a My\Custom\Service\Provider into app/config/app.php's 'providers' and the alias for the facade
What's the difference between them? Why and when should I use any of those ways? Should I load a class, several .php files or simply the folder? Maybe reference those 3 things at the same time?
EDIT:
These are my guesses:
Option 2 is just for packages
Option 3 if you want to load every class inside a custom namespace declared within the new created folder (don't get why the "psr-0" instead of just adding it to "classmap")
Option 1 is the same as option 3, just handled by Laravel instead of Composer
You can reference a folder and it will load every class found inside, or you can reference a certain file and it will load the class found inside
About option 4:
If you want to use the facade anywhere on your code, and that will need the namespace added into composer.json
EDIT 2:
If you add them to "classmap":
"classmap": [
"app/libs"
]
every class from any namespace within files inside the app/libs folder, will be loaded
If you add them to "psr-0":
"psr-0": {
"Libs": "app/"
}
it will load every class within the Libs namespace inside the app/libs folder
Still not sure why/when to use service providers and aliases.
EDIT 3:
"psr-0" if I want to load a namespace that follows a folder structure (it won't load a class within a subnamespace if it doesn't match the folder structure)
"classmap" for "random" classes, functions... sort of "the rest"
you can load your own code 2 (maybe 3) ways in laravel.
use composer
use ClassLoader
Manual include or require anywhere
Option 2 is just for packages
yes, you're right.
Option 1 is the same as option 3, just handled by Laravel instead of
Composer
yes, you're right.
Option 3 if you want to load every class inside a custom namespace
declared within the new created folder (don't get why the "psr-0"
instead of just adding it to "classmap")
some packages or classes adhere psr-0 standard, the rest is not. psr-0 option is mapping namespace to directory. the classmap is mapping
the namespace to certain directory or file and used for the class that is not adhere psr-0 standard.
You can use the classmap generation support to define autoloading for all libraries that do not follow PSR-0/4.
If you want to use the facade anywhere on your code, and that will
need the namespace added into composer.json
nope, instead, you have to add class alias for the facade in app/config/app.php
if your code is just file, not a class, then use composer autoload files
if your code is class but not adhere psr-0/4 standard, use composer autoload classmap or just add the containing directory to app/start/global.php.
otherwise, use composer autoload psr-0 or psr-4.
in Laravel 4,I add all of my class in "mylibrary" folder.
Then at app/start/global.php , I add app_path().'/mylibrary',
ClassLoader::addDirectories(array(
app_path().'/commands',
app_path().'/controllers',
app_path().'/models',
app_path().'/database/seeds',
app_path().'/mylibrary',
));
Within mylibrary there is MyClass.php , within MyClass.php there is test_myfunction()
and at app/view/home.blade.php I add these code :
<?php
$FMyClass11 = new MyClass;
$just_test=($FMyClass1->test_myfunction());
?>
Hope it works for you. :)
I am new to the kohana php framework. In the modules folder in kohana 3.1, there are many empty files extending the existing classes. Should I write my code in those empty files?
If yes, do I have to make any changes in bootstrap?
If not, where should I place these files? Should they be in a subfolder inside the Application directory or inside the modules directory?
Which all files will I have to copy from the modules to application?
Those empty files you see are aliases created for the class. An example would be the Cookie class, declared as so:
class Cookie extends Kohana_Cookie {}
It's just another way for you to refer to the real class, in this case Kohana_Cookie, without having to type all that out.
So when you use something like Cookie::salt($name, $value) you're really just using Kohana_Cookie::salt($name, $value).
If you want to extend a class, you can drop the files into your application/classes folder and go from there.
check out the docs at http://kohanaframework.org/3.1/guide
especially: http://kohanaframework.org/3.1/guide/kohana/files
you can extend classes in the folder: application/classes/.. or modules//classes/..