I'm still having problems getting composer to work. When not using composer autoloading, I can require_once the class file and instantiate an object. However, when attempting to use autoloading, I receive this error:
PHP Fatal error: Uncaught Error: Class 'MyCompany\User' not found in /var/www/html/portal/login.php:7
Stack trace:
#0 {main}
thrown in /var/www/html/portal/login.php on line 7
login.php looks like this:
<?php
require_once __DIR__ . "/vendor/autoload.php";
use MyCompany\User;
$user = new User();
The current composer.json looks like this:
{
"autoload": {
"psr-4": {
"MyCompany\\User\\": "vendor/mycompany/user/"
}
},
"require": {
"mycompany/user": "dev-master"
},
"repositories": [
{
"packagist.org": false
},
{
"type": "vcs",
"version": "master",
"url": "git#mysrc.example.com:/opt/git/phplib/classes/User.git"
}
]
}
The User.php file is this:
<?php
namespace mycompany;
class User {
function __construct() {
print "composer has done something\n";
}
} //end class User
?>
Finally, folder structure is:
portal\
composer.json
login.php
vendor\
mycompany\
\user\User.php
\pdo\PDO.php
\page\Page.php
Somehow namespacing seems to be the underlying issue but I'm not sure how to set it up in order to support this structure. Ultimately, even if the namespace is "mycompany" that would be fine but no combinations of namespace in the class, composer.json autoload statement, and use statement have worked. I have looked through countless questions here and none seem to match this exact scenario. This is on a linux system and I have also tried various combinations of upper and lower case for files and folders, though some fail because composer won't allow uppercase in certain areas.
Related
I have problem with autoloading with composer when i use psr-4 autoloading it doesn't work and give me error.
I tried:
$ composer dump-autoload
and a lot of other thing but it doesn't work without
require one;
error:
You are now a master builder, that knows how to autoload with a
classmap!
Fatal error: Uncaught Error: Class 'VegithemesLibraryGreeting' not
found in /home/vaclav/Server/vssk/VSSK/project/aldemo/index.php:10
Stack trace: #0 {main} thrown in
/home/vaclav/Server/vssk/VSSK/project/aldemo/index.php on line 10
composer.json:
{
"autoload": {
"files": ["mylibrary/functions.php"],
"classmap": [
"classmap"
],
"psr-4": {
"one\\": "src/"
}
}
}
greeting.php (file with class to load):
<?php
namespace one;
Class Greeting
{
public function hi()
{
return "We got you covered";
}
}
index.php file:
<?php
require 'vendor/autoload.php';
echo lego();
$cm = new Cmautoload;
echo $cm->classmap();
$vt = new oneGreeting;
echo $vt->hi();
It is generally good practice to capitalize the first letter of a class name. It also adheres with the rules of PSR-1.
Change your composer.json file to look like this:
{
"autoload": {
"files": [
"mylibrary/functions.php"
],
"classmap": [
"classmap"
],
"psr-4": {
"One\\": "src/"
}
}
}
Now, in your index file. We are going to import the autoloader. To do this simply require it:
require 'vendor/autoload.php';
Now that you have included the autoloader, go into every class and set the namespace.
The classes in your src/ == namespace One;
Check your classes in src/ and make sure they are all namespaced. Meaning that they should all have the following line of code at the top:
namespace One;
As mentioned before, update your file names to Foo.php and class names to
class Foo to adhere to PSR. (This is not required but highly recommended and standard procedure.)
To use one of your classes you would say use One\Greeting;
$greeting = new Greeting();
echo $greeting->hi(); //"We got you covered"
I found the problem, there was missing:
use One\Greeting;
In a lot of tutorials there isn't a word about it.
Another relevant detail about this is the namespace must match with the folder structure.
If not it will throw the warning.
In my case the filename was
src/One/GreetingClass.php
but the class name was in lowercase, causing this error:
class Greetingclass {
Changing the class declaration as GreetingClass fixed the issue.
Hi there,
I'm fairly new in working with composer, but I'm experiencing issues. After some stackoverflow searches I tried some of te solutions, however, none of them did work for me. I Have the following error:
Fatal error: Class 'Freeby\Basic\Navigator' not found in index.php on line *.
So I took a look at my index. It contains the following code:
index.php
namespace Freeby;
use \Freeby\Basic\Navigator as Navigator;
Navigator::execute();
The line where the error occurs is the last one, Navigator::execute();. So I went to take a look at this class found in the folder Basic. Navigator.php
namespace Freeby\Basic;
class Navigator
{
public static function execute()
{
}
}
So, I have my namespace there. It should be recognized. However, it does not. So I went on to check my composer.json.
{
"require": {
"mikecao/flight": "^1.3"
},
"autoload": {
"psr-4": {
"Freeby\\Basic\\": "Basic/"
}
}
}
And I think this one is correct. However I'm not that sure. To be sure I'll include my structure here too. Maybe it's a path issue? If yes, why? I Couldn't find it.
---- Basic
- Navigator.php
---- Vendor
- autoload.php
-- composer
---- composer.json
I think you need to load the composer autoloader first in index.php
<?php
namespace Freeby;
require __DIR__."/vendor/autoload.php";
use \Freeby\Basic\Navigator as Navigator;
Navigator::execute();
I'm developing a REST API with Silex and I'm facing a problem regarding autoloading of my custom librairy. It looks like Composer's autoload is not including it, because when I include it myself it works.
# The autoload section in composer.json
# Tried with :
# "Oc\\": "src/Oc"
# "Oc\\": "src/"
# "": "src/"
"autoload": {
"psr-4": {
"Oc\\": "src/"
}
}
<?php
// api/index.php <-- public-facing API
require_once __DIR__.'/../vendor/autoload.php';
$app = require __DIR__.'/../src/app.php';
require __DIR__.'/../src/routes.php'; // <--
$app->run();
<?php
// src/routes.php
// When uncommented, it works!
//include('Oc/ParseImport.php');
use Symfony\Component\HttpFoundation\Response;
use Oc\ParseImport;
$app->get('/hello', function () use ($app) {
return new Response(Oc\ParseImport(), 200);
});
<?php
// src/Oc/ParseImport.php
namespace Oc {
function ParseImport() {
return 'foobar!';
}
}
I run composer dumpautoload after each composer.json manipulation, and I do see the line 'Oc\\' => array($baseDir . '/src/Oc') (or anything I tried) in vendor/composer/autoload_psr4.php.
I can't figure out what is wrong.
Almost everything you did was correct.
When trying to autoload classes in a namespace, given that a class is named Oc\Foo and is located in the file src/Oc/Foo.php, the correct autoloading would be "PSR-4": { "Oc\\": "src/Oc" }.
However, you do not have a class. You have a function. And functions cannot be autoloaded by PHP until now. It has been proposed more than once (the one proposal I found easily is https://wiki.php.net/rfc/function_autoloading), but until now this feature hasn't been implemented.
Your alternative solutions:
Move the function into a static method of a class. Classes can be autoloaded.
Include the function definition as "files" autoloading: "files": ["src/Oc/ParseImport.php"] Note that this approach will always include that file even if it isn't being used - but there is no other way to include functions in PHP.
As illustration see how Guzzle did it:
Autoloading in composer.json
Conditional include of functions based on function_exists
Function definition
Is it possible in some way to instantiate a class inside a namespace, in a method in another class inside another namespace? And with the requested class instantiated from a variable?
Example:
Class to be loaded from loader-class:
namespace application/pages;
class loader
{
private function __construct()
{
echo 'Class loaded...';
}
}
Loader-class:
namespace system/loader;
class loader
{
private $vars;
private function __construct($vars)
{
$this->vars = $vars;
}
private function load_class()
{
require(CLASSES . $this->vars['namespace'] . '/' . $this->vars['class'] . ".php");
use $this->vars['namespace'];
return new \$this->vars['namespace']\$this->vars['class']();
}
}
Sorry for the bit confusing formulation, but i couldn't think of better way to ask the question.
Thanks.
This is the general way to load in namespaces:
http://www.php.net/manual/en/function.spl-autoload.php
However there is a more popular way of doing it using Composer.
Download composer.phar and inside your project directory run: php composer.phar init
Following the interactions.
In your project root, create a src directory then add this to your composer.json file which generated: "autoload": { "psr-0": { "": "src/" } }
Your composer.json file should now look like this:
{
"name": "acme/sample",
"authors": [
{
"name": "Person",
"email": "person#example.com"
}
],
"minimum-stability": "dev",
"autoload": {
"psr-0": { "": "src/" }
},
"require": {
}
}
Run: php composer.phar install, which will generate a vendors directory and an autoload script.
Create your primary load php file and include the autoload.php file inside.
Now, your namespaces inside the src directory and any imported libraries in vendor, will be exposed to your application.
Checkout symfony/symfony-standard to see a full framework example.
I'm experimenting with creating an extension with the Silex php micro framework for user authentication but I can't seem to get the autoloader to work. Can anyone shed any light?
I have a directory structure like this (truncated)
usertest
|_lib
| |_silex.phar
| |_MyNamespace
| |_UserExtension.php
| |_User.php
|_www
|_index.php
The pertinent bits of index.php, which serves as the bootstrap and the front controller look like this:
require '../lib/silex.phar';
use Silex\Application;
use MyNamespace\UserExtension;
$app = new Application();
$app['autoloader']->registerNamespace( 'MyNamespace', '../lib' );
$app->register( new UserExtension() );
The class I'm trying to load looks similar this:
namespace MyNamespace;
use Silex\Application;
use Silex\ExtensionInterface;
class UserExtension implements ExtensionInterface {
public function register( Application $app ) {
$app['user'] = $app->share( function() use( $app ) {
return new User();
});
}
}
All pretty straight forward except it throws this error:
Fatal error: Class 'MyNamespace\UserExtension' not found in /home/meouw/Projects/php/usertest/www/index.php on line 8
I have dabbled with symfony2 and have successfully followed the instructions for setting up the universal class loader, but in this instance I am stumped. Am I missing something? Any help would be appreciated.
In recent versions of Silex the autoloader is deprecated and you should register all your namespaces through the composer.json file which imo is a nicer solution because you are centralizing your autoloading definitions.
Example:
{
"require": {
"silex/silex": "1.0.*#dev"
},
"autoload": {
"psr-0": {
"MyNameSpace": "src/"
}
}
}
In fact when you try to access the autoloader in any recent version of Silex the following RuntimeException is thrown:
You tried to access the autoloader service. The autoloader has been removed from Silex. It is recommended that you use Composer to manage your dependencies and handle your autoloading. See http://getcomposer.org for more information.
I'd use
$app['autoloader']->registerNamespace('MyNamespace', __DIR__.'/../lib');
Deprecated - As of 2014-10-21 PSR-0 has been marked as deprecated.
PSR-4 is now recommended as an alternative
That is why you should use PSR-4 syntax in composer.json
{
"require": {
"silex/silex": "1.0.*#dev",
},
"autoload": {
"psr-4": {
"Vendor\\Namespace\\": "/path"
}
}
}
To register namespaces, just call registerNamespaces() like this:
$app = new Silex\Application();
$app['autoloader']->registerNamespaces(array(
'Symfony' => __DIR__.'/../vendor/',
'Panda' => __DIR__.'/../vendor/SilexDiscountServiceProvider/src',
'Knp' => __DIR__.'/../vendor/KnpSilexExtensions/',
// ...
));
Both adding appropriate statement to the autoload section of composer.json and registering namespaces directly calling registerNamespace was not working for me, until I executed composer update in the projects folder.