I know this question has already been asked, but it seems that autoloading process changed a little bit with composer.
I just want to add a class library to my silex project.
So I made this file:
vendor\lib\picture.php
<?php
namespace MyNamespace;
class Picture
{
function testage()
{
echo 'hihaaa ça marche'; exit;
}
}
in vendor/composer/autoload_namespaces.php, I added this line to the big array:
'MyNamespace' => $vendorDir . '/lib/',
And in the main file I added:
use MyNamespace\Picture as Picture;
and called it like that:
$app->register(new Picture());
which gives me this error:
Fatal error: Class 'MyNamespace\Picture' not found...
I just don't know how to add a class that I can use from any controller, easily, without command line (I don't use composer, I downloaded silex preconfigured), any idea?
If you're using composer you should not change the vendor directory. You should not add files into it, and you should not modify the composer-generated files.
I recommend you put those classes into the src directory. #gunnx shows how you can configure autoloading in composer.json, so that it gets re-generated every time you run composer install.
The file would be in src/MyNamespace/Picture.php. The autoload config in composer.json would be:
{
"autoload": {
"psr-0": { "MyNamespace": "src/" }
}
}
The actual solution is a combination of the two previous answers. But I think it's important to get the details right ;-).
Your Picture class should be in this file: vendor/lib/MyNamespace/Picture.php. Note the full namespace and the casing.
You can add your own code to the autoloader by adding the following to your composer.json
e.g.
{
"autoload": {
"psr-0": {"Acme": "src/"}
}
Related
I am trying to use a class in my src folder, DependencyContainer, but it is saying class not found?
Index:
<?php
$dc = new \Mango\DependencyContainer();
File structure:
src/
DependencyContainer.php
index.php
composer.json
composer.json:
{
"name": "mqwerty/ioc-container",
"type": "library",
"require": {},
"autoload": {
"psr-4": {
"Mango\\": "src/"
}
}
}
DependencyContainer class:
<?php
declare(strict_types = 1);
namespace Mango;
class DependencyContainer
{
}
First you need to add the autoload file in your index like this
require __DIR__ . '/vendor/autoload.php';
And your index.php is going to sth like this
<?php
require __DIR__ . '/vendor/autoload.php';
$dc = new \Mango\DependencyContainer();
It will solve your problem
Autoloading doesn't just happen automagically; composer is set up to manage the creation and updating of your PSR autoloading based off the PSR settings of your composer.json.
Do a composer install in your CLI; that will generate the autoload files in the vendor folder based off of your composer.json and create a composer.lock file, even if you don't have any dependencies.
From there, you will need to bootstrap the autoload file before executing your code.
Hey this has already been solved many times but ill still explain just incase you didnt understand others questions.
So I had this problem once too and you can find it on my profile.
psr works based on your path. when you set your src path thats where it starts from,
for example, your layout is something like the following:
vendor
your-vendor-name
your-package
src
App.php
Class.php
composer.json
then your psr location should have this after the : "/src"
and before it should be something like the following:
"your-vendor-name\your-package\"
when using a class, make sure you composer class names start with an uppercase letter and the class inside matches the file name, make sure the class namespaces are something like this \your-vendor-name\your-package
and to use
$app = new \your-vendor-name\your-package\(then the class name you want to use, so lets say, Class.php, then you would put Class() here)
hopefully this should solve your problem
I have a config.php file where I use autoload for all my personal classes
function __autoload($class_name) {
include __DIR__.'/classes/'.$class_name . '.php';
}
I need now to use a 3rd party class from composer which is located in
/vendor/guzzlehttp.
So my code is now:
require('Config.php'); // my config file: this is used in ALL site
require 'vendor/autoload.php'; // the copmoser
$client = new GuzzleHttp\Client([]); // call to the 3rd party class installed by composer
Which raises a 404 error : php searches GuzzleHttp in /classes
Uncaught Error: Class 'GuzzleHttp\Client' not found
I have no idea on how to solve that: I need to keep my own classes in /classes
I need to autoload them because all the website uses that.
So: how can I use classes installed by composer in my website?
My composer.json content is:
{
"require": {
"firebase/php-jwt": "^5.0"
}
}
Autoloaders can be stacked just fine, but you'll want a check in place to see if the file exists before trying to include it.
However, if you're using Composer already, just let Composer handle the autoloading.
Add a reference to your global namespace being loaded from the classes directory in your composer.json's autoload PSR-4 section:
"autoload": {
"psr-4": {
"": "classes"
}
},
__autoload() is deprecated and seems to be incompatible with current best practice, spl_autoload_register(), which is what Composer uses.
function myAutoload($class_name) {
include __DIR__.'/classes/'.$class_name . '.php';
}
spl_autoload_register('myAutoload');
But you should really look at moving your dependencies into that dependency manager that you already have, Composer.
For external libs that are already in Composer, like Guzzle: https://packagist.org/packages/guzzlehttp/guzzle
For internally-developed libs: https://getcomposer.org/doc/04-schema.md#autoload
Edit: on second look there's no reason #Devon's answer wouldn't work.
I'm currently developing a framework but I couldn't figure out how am I going to set autoloading. First I created a package with sample class and composer.json. I've autoloaded that sample class by:
"autoload": {
"classmap": [
"libs/"
]
}
I've checked /vendor/mypackage/vendor/composer/autoload_classmap.php and confirmed that package's autoloader is working fine. But the problem is I can't reach that package's class from main app unless I directly include that package's autoload.php.
UPDATE
/vendor/foo/mypackage/composer.json
"autoload": {
"psr-4": {
"Http\\": "libs/"
}
}
/vendor/foo/mypackage/libs/Request.php
namespace Http;
class Request {}
First of all, it's often better to use psr-0 or psr-4 autoloading config. With the classmap, you have to redump the autoloader each time you add a new class or rename one.
You always need to include the Composer autoloader by using require 'vendor/autoload.php';. The best place to add such require statement is in your front controller file.
Solved it by myself. I just had to reinstall package whenever I change pacakge's composer.json.
I play around with Silex, PHP micro-framework. At the moment I try to load my own classes but I have no luck doing it. Maybe somebody could explain me a little how does loading in Silex works?
My project structure looks like this:
app/
vendor/
web/
tests/
bootstrap.php
composer.json
composer.lock
Let's say I want to load a class Controller\User (namespace here) from /app/MainController.php.
How can I do that? I've browsed some articles (loading via Composer or Symfony's UniversalClassLoader), followed some instructions, and still it does not work.
If someone could give me a hand with it please, I would appreciate it.
I assume you load your Silex classes in bootstrap.php like that:
// bootstrap.php
require_once __DIR__.'/vendor/autoload.php';
If so replace this code with the following:
// bootstrap.php
$loader = require __DIR__.'/vendor/autoload.php';
$loader->add(YOUR_NAMESPACE, DIRECTORY_OF_THE_NAMESPACE);
Example:
// bootstrap.php
$loader = require __DIR__.'/vendor/autoload.php';
$loader->add('Tutorial', __DIR__.'/src');
You can add multiple namespaces if you like, just call the add method for every namespace.
In src/ you would store your class files. For every namespace create a folder which contains your class files for this namespace.
The file should have the same name as the class.
MyNamespace\MyClass => src/MyNamespace/MyClass.php
MyNamespace\SubNamespace\SubClass => src/MyNamespace/SubNamespace/SubClass.php
In every class file you have to set the associated namespace in the first line.
// src/Tutorial/DemoController.php
namespace Tutorial;
class DemoController{
// class definition goes here..
}
You have now access to your classes in every file which includes bootstrap.php.
In /app/MainController.php you can now access your own class like this:
// app/MainController.php
use Tutorial\DemoController;
$foo = new DemoController();
This solution worked for me. Hope it works for you.
I was also looking for the same thing, since Silex documentation still has the registerNamespace function that was removed.
Found a really nice answer here
In Short, all you have to do, is add a "psr-0" in "autoload" section in the composer.json
Example composer.json:
{
"require": {
"silex/silex": "~1.3",
"doctrine/dbal": "~2.2"
},
"autoload": {
"psr-0": {
"MyApp": "src/"
}
}
}
Make sure to update the Composer Autoloader ("composer install" or "composer update")
As of October, 2014 the best way to autoload your own classes into silex, is using PSR-4 (instead of PSR-0) autoloading through Composer using composer.json file in your application root:
{
"require": {
"silex/silex": "~2.0",
},
"autoload": {
"psr-4": {"Vendor\\Namespace\\": "path/to/src/"}
}
}
After editing your composer.json you need to do a:
composer update
on your project root directory, using terminal.
I've started a new project, where I use Composer to handle some dependencies, as well as their auto-loading.
I only keep the composer.json file in the VCS, instead of the entire vendor directory, so I don't want to start adding my code in there.
How should I handle my own project specific code, so that it auto loads as well?
This is actually very simple. Excluding vendors directory from your repository is the right approach. Your code should be stored in a separate place (like src).
Use the autoload property to make that composer recognizes your namespace(s):
{
"autoload": {
"psr-4": {
"Acme\\": "src/"
}
}
}
Assuming you have class names following the psr-4 standard, it should work. Below some example of class names and their locations on the file system:
Acme\Command\HelloCommand -> src/Command/HelloCommand.php
Acme\Form\Type\EmployeeType -> src/Form/Type/EmployeeType.php
Remember to define a namespace for each class. Here's an example of Acme\Command\HelloCommand:
<?php
namespace Acme\Command;
class HelloCommand
{
}
Don't forget to include the autoloader in your PHP controllers:
<?php
require 'vendor/autoload.php';
Read more on PSR-4 standard on PHP Framework Interoperability Group.
Note that if you edit composer.json, you need to either run install, update or dump-autoload to refresh the autoloader class paths.