I'm still quite new to namespaces and struggle to get my head around how to use them. I'm using Silex Microframework and trying to set up my folder structure. So far I have:
cms/
ACP/
Controller/
HomeController.php
View/
Front/
Controller/
HomeController.php
View/
Template/
page.php
home.php
app.php
bootstrap.php
I'm trying to load the HomeController in the Front/Controller folder. In my app.php file I am calling the controller for home.
require_once __DIR__.'/../vendor/autoload.php';
$app = new Silex\Application();
$app['debug'] = true;
$app->get("/", "cms\Front\Controller\HomeController::index");
$app->get('/test', function() {
return new Symfony\Component\HttpFoundation\Response("Test successful");
});
return $app;
If I go to /test in the browser it works fine. However when I go to / then I get an error.
InvalidArgumentException in ControllerResolver.php line 153:
Class "cms\Front\Controller\HomeController" does not exist.
I've defined cms as a namespace in composer.json and in HomeController I have
<?php namespace cms\Front\Controller;
class HomeController {
public function index() {
return "Hello World, I'm the front page!";
}
}
I've also tried moving the HomeController.php file directly into the cms directory, changing the namespace in the file to just cms and then running $app->get("/", "cms\HomeController::index"); and it still doesn't work. I get the same error that doesn't exist.
Here is my composer file:
{
"require": {
"silex/silex": "~1.1",
// ...other requirements
},
"require-dev": {
"symfony/var-dumper": "dev-master"
},
"autoload": {
"psr-0": {
"cms": "cms/"
}
}
}
What do I need to do to get this working? I can't seem to find anything on the Silex site or Google. Can someone please help me get my head around namespaces and how this works?
You need to add your source folder into the composer autoloading (https://getcomposer.org/doc/01-basic-usage.md#autoloading)
"autoload": {
"psr-4": {"Acme\\": "./"}
}
In your case the path "./" should work (have not tested), if not you should try to put cms folder into a folder like src and set the path to "src/"
Remember to run composer dump-autoload to regenerate the autoload.php
Related
I've been testing getting my packages up to Packagist with a simple class I made. Whenever I require it in a different project, it says the class cannot be found. Is something wrong with my composer.json autoload block?
Here's my project repo file structure:
- src
- prodikl
- View.php
- .gitignore
- composer.json
And here's my composer.json:
{
"name":"prodikl/simple-view",
"description":"A simple to use, basic View object.",
"require" : {
"php" : ">=5.3.0"
},
"autoload": {
"psr-4": {"prodikl": "src/"}
}
}
And finally, in my View.php:
<?php
namespace prodikl;
class View
{
...
}
But whenever I require it into a project and do require "vendor/autoload.php" and use use prodikl\View; it it keeps saying not found
You just need to point your autoloader down one more directory:
"autoload": {
"psr-4": {"prodikl": "src/prodikl/"}
}
This means "classes that belong to the \prodikl namespace can be found in the src/prodikl/ directory."
You might need trailing backslashes on the namespace name too, not sure how picky Composer is about it:
"psr-4": {"prodikl\\": "src/prodikl/"}
I want to load HomeController class from lib directory:
root/
-lib/
--/HomeController.php
-vendor/
-composer.json
-index.php
Composer.json
"autoload": {
"psr-4": {
"Lib\\": "lib/"
}
}
HomeController.php
namespace Lib;
class HomeController {}
index.php
var_damp(new \Lib\HomeController.php);
It doesn't find the class.
But if I put HomeController.php inside Controllers directory:
root/
-lib/
--/Controllers/HomeController.php
And update the namespaces: index.php to var_damp(new \Lib\Controllers\HomeController.php); and HomeController.php to:
namespace Lib\Controllers;
class HomeController {}
It works perfect.
It's weird, I can't find any docs talking about it. I don't need additional directories, in this case I want the HomeController class directly inside lib directory.
How can I make it works inside lib folder?
I think the trailing slash in the path reference is your problem. Change the autoload section in composer.json to this:
"autoload": {
"psr-4": {
"Lib\\": "lib"
}
}
...then run composer dump-autoload.
I get this error when I try to use autoload and namespaces. All my namespace classes are under app/libs/
16-Dec-2016 04:30:50 Europe/Berlin] PHP Fatal error:
Class 'App\libs\App' not found in /Users/mysite/app/page1.php on line 26
Here is My code:
require '../public/vendor/autoload.php';
use App\libs\App;
use App\libs\Auth;
class Controller
{
public $app;
public function __construct()
{
#set_exception_handler([$this, 'exceptionHandler']);
$this->app = new App();
}
}
autoload normally includes files only under vendor folders. It does not load any other files, if you do not instructe to. You are probably using composer. if it is, you can add folders in composer.json file to include class files from other folders like App\libs. An example a composer.json file is:
{
"require": {
"twig/twig": "~1.0"
},
"autoload": {
"psr-4": {
"App\\": "App/"
}
}
}
In the examle above, it will autoload any files under App folder.
Finally you need to run: composer dump-autoload to make this working.
I have structure directory
autoload composer:
"autoload": {
"psr-4": {
"model\\": "src/"
}
},
my class
namespace model;
class ClientAgent
{
private $pdo;
public function __construct(\PDO $pdo)
{
$this->pdo = $pdo;
}
public function sentAgent()
{
}
}
in index.php i tried add
use model\ClientAgent; but it throw error, not found class? why?
Edit after answer
"autoload": {
"psr-4": {
"model\\": "src/model/"
}
},
my index.php
use model\ClientAgent;
$loader=require_once __DIR__ . '/../vendor/autoload.php';
$clientAgent =new ClientAgent($pdo);
error
Uncaught Error: Class 'model\ClientAgent' not found in C:\xampp\htdocs\Wieloagenty\index.php:15
My suggestion is to introduce a vendor prefix. That might be your developer name, the name of your company or the name of the application.
composer.json
"autoload": {
"psr-4": {
"YourApplication\\": "src/"
}
},
Now, every class inside the src folder and below needs this vendor prefix on it's namespace.
Let's take src\model\ClientAgent.php as example:
namespace YourApplication\Model;
class ClientAgent
{
Now, the FQCN (full qualified class name) is YourApplication\Model\ClientAgent and you might use it as part of a use statment.
// first require the Composer autoloader
require_once __DIR__ . '/../vendor/autoload.php';
// declare which other classes you are using
use YourApplication\Model\ClientAgent;
$clientAgent = new ClientAgent($pdo);
Important!
After the modifications (to classes and the composer.json file) please regenerate the Composer autoloader with php composer.phar dumpautoload -o.
Composer will scan the complete src folder including subfolders for classes (so you'll have all classes from src\models\ and src\views autoloading ready).
"model\\": "src/" will give you the folder src/ as the base for the model-namespace. So this would give you model\model\Classname.
Change it to:
"psr-4": {
"model\\": "src/model/"
}
When defining psr-4 autoloader in composer, you associate a folder with a specific namespace.
Any sub folders will be a sub-namespace. So if you create a folder in your "model"-folder, the namespace would be: model\new-foldername\Classname and so on.
Note: When ever you update your composer.json file, you always need to run the command: composer dump-autoload to make composer regenerate all it's cached files.
This is my actual composer.json file
"autoload": {
"psr-0": {
"Raggaer": "app/"
}
}
My file structure is the following:
app
bootstrap
controllers
views
Inside bootstrap I got app.php and start.php
Start.php
$app = new App($uri);
App.php
namespace Raggaer\Bootstrap;
class App { .. }
And im getting the following error
Fatal error: Class 'Raggaer\Bootstrap\App' not found