Composer autoload with our naming convention - composer-php

Our naming convention for classes has been name_class.php. Is there a way to append _class in the class file name look up? I changed the loadClass function in the ClassLoader.php file to get it to work but a composer install overwrites my change.

No, composer does only support PSR-0, PSR-4 and for all other schemes the classmap.
If your name scheme does not conform to PSR-0 at least, all you can do is to use the classmap and always create a classmap update if you add a new class. I'd highly recommend to create new classes conforming to PSR-4 or PSR-0 standard to get rid of this need when using Composer. The old classes might still be located somewhere and loaded via classmap if you do not want to rename the files.
You can however run the composer autoloader parallel to your own. Then you are still responsible for your own classes, but use Composer for all the libraries.

Related

how laravel handle illuminate namespace

As far as I know, namespace is used for preventing class, function, ... collision in PHP. In Laravel 8 when we create a model for example, the name space is App\Models and when we want to use this model, we have to use it like use App\Models\MyModel. My question is when we use use Illuminate\Support\Arr, why we don't use the full path explicitly vendor\laravel\framework\......
It’s part of the PSR-4 auto loading standard which replaces the PSR-0 auto loading standard. Composer compiled an autoload.php from your project’s and dependencies’ composer.json. As part of the bootstrapping process that file is included in the application and registers each namespace.

How to use a vendor class in Laravel?

I would like to use this package https://github.com/FineUploader/php-traditional-server/ in my Laravel project. So I modified composer.json file like that:
"require": {
"php": ">=5.5.9",
"laravel/framework": "5.2.*",
"fineuploader/php-traditional-server": "1.0.0"
}
And run a compose update command. But how can I use UploadHandler class (declared in handler.php of the package) on my Controller?
The package isn't using namespaces or much else the Composer autoload could provide magically for you, so you could either include the class file yourself:
include "vendor/FineUploader/php-traditional-server/handler.php";
or as you are using the Composer autoloader in Laravel, you should define a classmap.
In your composer json:
{
"autoload": {
"classmap": ["vendor/FineUploader/php-traditional-server"]
}
}
Then run composer dump-autoload
(including "vendor/autoload.php" is already provided by the Laravel boot).
All the classes in their library will be auto-loaded at the moment your code requires them.
Update: why classmap is the most suitable method.
Autoloading is the most efficient and performant way to load a class, because it is only parsed, compiled, loaded into memory when the class is actually needed. "Classmap" autoloading is the intended mechanism to load classes which are not in a namespace, or are not in PSR0 or 4 format.
Conversely, using a global (app boot) include set for classes, or similarly using the "files" option in the composer autoloader would be the most inefficient as it would load all dependencies for all application requests, regardless of whether they are going to be used or not. In fact using autoload "files" for class dependencies is worse than the traditional approach of having specific includes in each of your scripts. At least then you would only pre-loading the specific requirements, thus similar to autoload in memory usage.
The "files" autoload option is intended for flat libraries of functions (not OO), which are simply pre-loaded on all requests, because there is no auto-load mechanism for function calls.
Note the use of op-code caches would soften the efficiency difference between the two, but the memory usage issue remains.
#scipilot answer should work too, but I will give my own choice:
Add this part to Your composer.json file and run composer update.
"files": [
"vendor/fineuploader/php-traditional-server/handler.php"
]
After this, class will be visible in project scope and Your script will work.
More about auto loading files in composer here: https://getcomposer.org/doc/04-schema.md#files
Did you try use UploadHandler directly?
Composer have autoloading feature, so it can pick up your "dependencies" on the fly

Composer autload check for already loaded classes

I'm using Composer dependency manager for php in my project. I'm building my project to off open source CMS called Concrete5. They are also loading stuffs with Composer.
Concrete5 and my own package for that uses Doctrine and Doctrine is included in both composer.json files. Do I have problem in autoloading when loading Doctrine in two different locations?
Composer and most other autoloaders use the standard PHP spl_register_autoload() function to keep track of the autoloading stack. This combined with the rules of PSR-0 and PSR-4 allow every registered autoloader a chance to fulfill a dependency for your code.
So when you have two autoloaders that can fulfill the same dependency, whichever one gets a chance to respond first wins. To help with this, spl_register_autoload provides a way to prepend autoloaders to the stack so that they run first. With composer this actually happens by default, the way to disable it so that the you can load the core versions of the dependency is to set prepend-autoloader to false in your package's composer.json.
{
"prepend-autoloader": false
}
Another option entirely is to define provide in your packages composer.json with proper versions for the dependencies that the core provides (you can find this in concrete/composer.lock).
{
"provide": {
"doctrine/dbal": "v2.5.1",
"doctrine/orm": "v2.4.8"
}
}
This will prevent composer from pulling down duplicate versions of dependencies, the downside to this is that you'll need to keep this list up to date manually when the core updates its dependencies.

Laravel 5 namespaces

I just downloaded Laravel 5 and started migrating to it. However, I find the required use of namespaces really annoying.
I don't feel like I am getting much from it, other than cluttering my code.
How can I disable the namespacing requirement?
I don't think you should disable or remove namespaces. The main reason for namespacing is to avoid conflicts with classes that have the same name. As soon as an application gets larger you will have classes that have the same name. Example from the Framework source:
Illuminate\Console\Application and Illuminate\Foundation\Application
Both are called the same. Only because of the namespacing you can import the right class. Of course you could also name them:
ConsoleApplication and FoundationApplication
But while the namespace normally is only used when importing a class at the top of a file:
use `Illuminate\Console\Application`
The name itself is used everywhere in the code. That's something that really clutters up your code, too long class names.
Besides the naming thing, namespaces also encourage better structure and help with knowing where your files are. That's because Laravel's default structure is PSR-4 compliant. That means if you have a controller App\Http\Controllers\HomeController you can be certain that you will find a HomeController.php under app/Http/Controllers.
I am aware of that, but it's not needed in the project I am working on.
Maybe it doesn't make sense for the current project but getting used to namespaces will help you tackle bigger projects in the future
And being a Sublime Text user, which doesn't have autoimport, it really gets to be a pain
I don't know Sublime Text that well, but CodeIntel might have auto import. Otherwise consider switching to another editor / IDE. I can highly recommend JetBrains PhpStorm
In the end, if you still don't want to use namespaces, keep using Laravel 4 or search for another framework that follows less good practices...
Removing namespaces from your app classes
While a totally don't recommend this, it is possible to at least remove some of the namespacing in your application.
For example the default controller namespace App\Http\Controllers can be changed to no namespace at all in RouteServiceProvider:
protected $namespace = '';
And for your models you can just remove the namespace in the file and your good. But keep in mind that without namespaces PSR-4 autoloading won't work anymore. You will have to autoload your files using classmap in composer.json
You can avoid using namespaces for own classes by defining them in the global namespace in your composer.json file. Like this:
"autoload": {
"psr-0": {
"": ["app/Http/Controllers/",
"app/models/",
"app/helpers"
]
},
You will also have to change your app/Providers/RouteServiceProvider.php to:
protected $namespace = '';
for routing to work.

Why you need to manually register classes via composer in in Laravel?

I come from a CodeIgniter background and everytime I create a new controller, I don't have to register it by calling a program like composer.
Why this is required in Laravel?
This is because Laravel uses the "Classmap" autoloading mode in Composer. With this, it scans the specified directories and compiles a class map. Because of this, you need to run composer dump-autoload when you add a new class, so that it can update the compiled class map.
However, it is fairly easy to use PSR-4 autoloading with Laravel. This autoloading standard requires you to follow stricter namespacing rules with your class names and filenames.
To use PSR-4, you'll need to namespace your controllers, models, etc. like this:
Yourname\Yourproject\Controllers
Yourname\Yourprject\Models
etc. You'll also need to change the controllers, models, etc. directories to be capitalized - Controllers, Models, etc., - to match the namespaces. Then, add this to your composer.json file:
"autoload": {
"psr-4": {
"Yourname\\Yourproject\\": "project_dir/app/"
}
}
This will map the Yourname\Yourproject namespace to the app directory. So, for example, to find the class Yourname\Yourproject\Controllers\FooController, Composer will automatically know to look in app/Controllers/FooController.php. At the top of FooController.php, write
<?php
namespace Yourname\Yourproject\Controllers
class FooController extends \Controller {
...
(Note: It's not required to namespace everything with Yourname\Yourproject\; it's recommended, but a simple Yourproject\ will work as well.
You can still also add an autoload.classmap section to your composer.json for classes that don't follow PSR-4, but you'll need to run composer dump-autoload for them.
For more information on the various autoloading modes in Composer, see here.

Resources