I just started using CakePHP 3. I'm trying to get up and running but doing the simplest of things is proving to be a headache.
I have a class, MySimpleClass, in src/App/MySimpleClass.php
<?php
namespace MyApp\MyNamespace;
class MySimpleClass {
public function aSimpleFunction() {
return 1;
}
}
And in my controller:
<?php
namespace App\Controller;
use Cake\Controller\Controller;
use MyApp\MyNamespace\MySimpleClass;
class MyFirstController extends Controller {
public function display() {
$mySimpleClass = new MySimpleClass();
echo $mySimpleClass->aSimpleFunction();
}
}
But this always gives me:
Error in: ROOT/src/Controller/TestController.php, line 10 Class 'MyApp\MyNamespace\MySimpleClass' not found
I use bin/cake server to run the HTTP server
I added App::className('MyApp\MyNamespace\MySimpleClass'); to bootstrap.php to see if that'd make a difference but it doesn't.
I've run composer dump-autoload on several occasions.
I tried putting MySimpleClass into global namespace but it still gave me the error.
PHPStorm isn't giving me any syntax or naming errors.
You should place your controllers in:
src/Controller
and use:
namespace App\Controller;
Nevermind, I finally found the solution...
I just had to add src to the classmap in composer.json:
"autoload": {
"classmap": [
"src"
],
...,
}
Edit:
Instead of abusing classmap, I just moved my class files to a directory outside of src
If your class is in the file src/App/MySimpleClass.php, the namespace has to be App\App. The first App refers to the root namespace of every CakePHP 3.x application, the second App refers to the subdirectory within the src directory you put your class file into.
If the namespace of the class should be App\MyNamespace, your classfile has to be located in src/MyNamespace.
Also: according to the error message you quoted, your MyFirstController is in a file called TestController.php. Instead, it should be MyFirstController.php. I recommend giving https://book.cakephp.org/3.0/en/intro/conventions.html#file-and-class-name-conventions a read regarding this topic.
Related
I am trying to organise my app a bit better by putting models and controllers in subdirectories. I thought it didn't matter if they were in subdirectories as long as the namespace is correct, but now that I've moved them I'm getting a class not found error.
I have tried running composer dumpautoload several times, but it's still not working.
Here is my directory structure:
App
Models
Managers
EntryStructure.php
FieldManager.php
Controllers
EntryControllers.php
Since I have made the new directory Managers and moved those two models in there, When I reference the FieldManager class from EntryStructure, I get the not found error.
Code in EntryStructure.php:
namespace Pascall\ICMS\Models;
use Pascall\ICMS\Models\FieldManager;
class EntryStructure
{
function index(){
new FieldManager(); // class not found
}
}
Code in FieldManager.php:
namespace Pascall\ICMS\Models;
class FieldManager {
//
}
Why is it not finding the FieldManager class when it is explicitly referenced in the use statement and they share the same namespace?
Your use should be
use Pascall\ICMS\Models\Managers\FieldManager;
instead
use Pascall\ICMS\Models\FieldManager;
If your Models directory follow the PSR-4 specifications, the namespace in both of your classes should follow the class file path, so it should be:
namespace Pascall\ICMS\Models\Managers;
Then, in EntryStructure class you should use:
use Pascall\ICMS\Models\Managers\FieldManager;
so i have the following structure for what i'm trying to target but what i'm getting is the Fatal error class MainController not found , i'm new to autoload and namespace thing (but getting into them fast) i just need to know why this is happening , hope you guys have bit explained situation for me? i did saw few of answer around stackoverflow but nuthing helped, i know i'm doing something really wrong, but thats how i will learn :). structure:
composer.json
src/controllers/MainController.php
the following is my autoload inside composer.json file:
"autoload": {
"psr-4": {
"controllers\\": "src/controllers/"
}
}
and this is how my MainController.php looks alike :
namespace MainController;
class MainController{
function test($name){
echo 'holaaaa'.$name;
}
}
controller call inside: app/loads/loadController.php :::
use MainController;
$MainController = new MainController();
more info on vendor/autoload.php
it's included inside : index.php and inside index.php i have included mainapp.php and inside mainapp.php i have included loadcontroller.php vich calls the controller
structure screenshot:
Okay, in your Composer file you say the namespace is controllers. In your PHP file you say the namespace is MainController. They need to be the same for the autoloading to work.
If we are to go by your Composer file then the PHP should look like this:
namespace controllers;
class MainController {}
And the class should be called like this:
$MainController = new \controllers\MainController;
Or like this:
use controllers\MainController;
$MainController = new MainController;
Or, if you want a nicer-looking class name:
use controllers\MainController as Controller;
$MainController = new Controller;
In my case I only managed to correct it after deleting my folder from the composer (vendor) and rerunning the command composer dump-autoload
The Laravel documentation clearly describes how to change your routes if you nest your controllers in folders. It seems REALLY simple, and yet I'm still getting an error. Here's the error:
"Class App\Http\Controllers\Input\InputController does not exist"
^That path looks 100% correct to me. What gives?
File Structure:
-Controllers
--Auth
--Input
---InputController.php
Routes:
Route::get('input', 'Input\InputController#getInput');
InputController:
<?php namespace App\Http\Controllers;
use Illuminate\Http\Response;
class InputController extends Controller
{
public function getInput()
{
return response()->view('1_input.input_form');
}
}
Thanks for any help!
Change Controller namespace from
namespace App\Http\Controllers
to
namespace App\Http\Controllers\Input
namespace needs to be changed to the directory your controller is in 'App\Http\Input'
You need to pull in Controller with use App\Http\Controllers\Contoller so that you can extend it.
<?php
namespace App\Http\Controllers\Input;
use App\Http\Controllers\Controller; // need Controller to extend
use Illuminate\Http\Response;
class InputController extends Controller
{
public function getInput()
{
return response()->view('1_input.input_form');
}
}
you should try running a couple commands in your base dir from your terminal (shell/prompt):
composer dump-autoload
or if you don't have composer set as executable:
php composer dump-autoload
and then:
php artisan clear-compiled
This way your laravel would prepare everything again "from scratch" and should be able to find the missing controller class.
Basically laravel generates some additional files to boot up faster. If you define a new class it doesn't get included into that "compiled" file. This way your class should be "introduced" to the framework.
I have a Symfony project to which I added some non-symfony php files containing various classes. But for some reason the classes are not loaded when loading the website, even though the IDE sees them properly.
So, I have a class that needs other classes:
namespace rootspace\FrontBundle\Controller;
use rootspace\FrontBundle\Networks\TwitterOAuth;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
class TwitterController extends Controller
{
public function connectAction(){
// The TwitterOAuth instance
$connection = new TwitterOAuth('abc', '123');
}
}
And then the class which fails to load (that needs yet another file)
namespace rootspace\FrontBundle\Networks;
/* Load OAuth lib. You can find it at http://oauth.net */
//require_once('OAuth.php'); -- should this be commented out?
/**
* Twitter OAuth class
*/
class TwitterOAuth {
/* Contains the last HTTP status code returned. */
}
Lastly, the third file
namespace rootspace\FrontBundle\Networks;
use Symfony\Component\Config\Definition\Exception\Exception;
class OAuthConsumer
{
public $key;
public $secret;
}
(...)
I assume the actual filenames don't matter, right? Nor their structure? PhpStorm sees all the classes properly, I can right-click through them, but it fails when deployed.
Thanks for help
Edit - the whole error message says
Attempted to load class "TwitterOAuth" from namespace "rootspace\FrontBundle\Networks" in D:\Dropbox\project\src\rootspace\FrontBundle\Controller\TwitterController.php line 15. Do you need to "use" it from another namespace?
This is because Symfony's autoloader follows PSR standards (PSR-0, PSR-4) which says that fully qualified (with namespace) class name translates to file location and name. So in fact file names does matter.
So in your case rootspace\FrontBundle\Networks\TwitterOAuth class should be located in rootspace/FrontBundle/Networks directory in file called TwitterOAuth.php
If classes you are using does not follow PSR standards you can also register them manually in app/autoloader.php file
Check these for more info:
How can I add a namespace to Symfony 2.1?:
How to autoload class
And check this answer
I forgot to add a .php extension to my filename
I'm using the Laravel framework and have a directory of the following structure:
models
Statistic.php
presenters
StatisticPresenter.php
In my models/Statistic class, I'm trying to access a present method which calls a protected property which then references my presenter:
protected $presenter = 'presenters\StatisticPresenter';
public function present() {
return new $this->presenter($this);
}
Yet, this returns the error: Class 'presenters\StatisticPresenter' not found. I realize this is a namespacing error of some sort, and I've tried watching a few videos on how it works, but I simply can't wrap my head around it. I have already added my presenter folder to my composer.json file. For example, adding this to the top of my Statistic model does not work:
use presenters\StatisticPresenter;
How can I fix this?
Do the followings;
Mark your namespace in StatisticPresenter.php ? (at the top of file "namespace presenters;")
Add PSR-4 class map to your composer
{
"autoload": {
"psr-4": {
"presenters\\": "app/presenters/"
}
}
}
run "composer dump-autoload" once and you wont need to run this command again for the "presenters" namespace if you add new classes into "app/presenters/ folder"
Test your class with "use presenters/StatisticPresenter;"
If you can access your class you dont need to change your code your present() function will be valid