I'm new to Laravel and using PHP namespaces in general. I didn't run into any problems until I decided to make a model named File. How would I go about namespacing correctly so I can use my File model class?
The files are app/controllers/FilesController.php and app/models/File.php. I am trying to make a new File in FilesController.php.
Namespacing is pretty easy once you get that hang of it.
Take the following example:
app/models/File.php
namespace App\Models;
class File {
public function someMethodThatGetsFiles()
{
}
}
app/controllers/FileController.php
namespace App\Controllers;
use App\Models\File;
class FileController {
public function someMethod()
{
$file = new File();
}
}
Declare the Namespace:
namespace App\Controllers;
Remember, once you've put a class in a Namespace to access any of PHP's built in classes you need to call them from the Root Namespace. e.g: $stdClass = new stdClass(); will become $stdClass = new \stdClass(); (see the \)
"Import" other Namespaces:
use App\Models\File;
This Allows you to then use the File class without the Namespace prefix.
Alternatively you can just call:
$file = new App\Models\File();
But it's best practice to put it at the top in a use statement as you can then see all the file's dependencies without having to scan the code.
Once that's done you need to them run composer dump-autoload to update Composer's autoload function to take into account your newly added Classes.
Remember, if you want to access the FileController via a URL then you'll need to define a route and specify the full namespace like so:
Route::get('file', 'App\\Controllers\\FileController#someMethod');
Which will direct all GET /file requests to the controller's someMethod()
Take a look at the PHP documentation on Namespaces and Nettut's is always a good resource with this article
first, load your class with:
$ composer dump-autoload
then
$file = new File;
// your stuff like:
$file->name = 'thename';
$file->active = true;
$file->save();
Section: Insert, Update, Delete on Laravel 4 Eloquent's doc
To namespace your model, at the top of your model class right after the opening
Then when you call from controllers you will call new Whatever\Model;
You probably have to do a dump-autoload with composer the first time around.
have a look to it.. hopefully will clear your query....
<?php
namespace app\controllers;
use yii\web\Controller;
use app\models\users;
class UserController extends Controller{
public function actionIndex()
{
echo "working on .....";
}
}
Namespaces are defined at the top of PHP classes right after the opening php script tag like this:
<?php
namespace MyNameSpace;
When you then want to use the namespaced class in some other class, you define it like this:
new MyNameSpace\PhpClass;
or import it at the top of the file (after namespaces if present) like this:
<?php
//namespace
use MyNameSpace\MyPHPClass;
//then later on the code you can instantiate the class normally
$myphpclass = new MyPHPClass();
In Laravel namespaces can be defined anywhere composer can autoload them, I'd recommend defining namespaces within the app directory. So you can define a namespace like Utils for holding Utility classes by creating a Utils directory in the app directory, creating our utility classes and defining the namespace as we did above.
Afterwards you have run the command to ask composer to autoload classes:
$ composer dump-autoload
Related
In my new laravel app I've added two custom classes. One loads fine when I use it in the controller, but the other, which is in another folder, does not work.
The working class, which I will call Working is located in app\Classes, it has the namespace namespace App\Classes and in the controller I call it with use App\Classes\Working.
The non-working class, which I will call NonWorking is located in app\Classes\NonWorking. I've tried giving it the namespaces namespace App\Classes and namespace App\Classes\NonWorking. From the controller I've tried calling it with use App\Classes\NonWorking and use App\Classes\NonWorking\NonWorking, but I get the error Class 'App\Classes\NonWorking' not found or Class 'App\Classes\NonWorking\NonWorking' not found.
I've been able to get it to run correctly by moving the NonWorking class into the same folder as the Working class and setting the namespace as namespace App\Classes, but the NonWorking class is from another repo and should be in its own folder as it will not be the only one from another repo.
So, how do I get Laravel to understand where this class is?
Laravel uses the PSR-4 autoloading. What it means is basically your class should follow the folder structure.
So if you have classes in app/Classes, they should have the namespace App\Classes.
So the file app/Classes/Working.php will have at its top namespace App\Classes; and to import it in another file, you write in the other file use App\Classes\Working;
If you have a class inside app/Classes/SubFolder, it should have the namespace namespace App\Classes\SubFolder;
So here is a class AmazingClass in app/Classes/SubFolder/AmazingClass.php file:
// app/Classes/SubFolder/AmazingClass.php
namespace App\Classes\SubFolder;
class AmazingClass
{
//
}
Let's use AmazingClass in another class.
// Some file in another namespace
namespace App\My\Random;
use App\Classes\SubFolder\AmazingClass;
// Rest of the file
Plus: Whenever you add a new class and you can't use it, it's likely that it's not autoloaded. Run the command
composer dump-autoload
to re-autoload the classes.
to solve your issue just create your folders and classes in App folder and run command :
composer dump-autoload
and they load all classes you have created
I created a class at Controller folder of Cake project like this:
<?php
class Hi
{
function __construct(){ }
public function hi()
{
echo "hi!";
exit;
}
}
Then in a controller, I tried to include it:
<?php
namespace App\Controller;
use App\Controller\AppController;
include_once "Hi.php";
class MyController extends AppController
{
public function sayHi()
{
$a = new Hi();
$a.hi();
}
}
Here is the error I'm having:
Fatal error: Cannot declare class Hi, because the name is already in use in path\api\src\Controller\Hi.php on line 2
What's going on?
MyController.php and Hi.php are in the same folder. I'm using PHP 7.
Including a file won't make the classes in that file part of the current namespace, as namespaces are a per-file functionality.
http://php.net/...namespaces.importing.php#language.namespaces.importing.scope
Your Hi class will be declared in the global namespace, and your new Hi() will cause PHP to look for it in the current namespace, ie it will look for App\Controller\Hi, which doesn't exist, hence the composer autoloader kicks in, and will map this via a PSR-4 namespace prefix match to src/Controller/Hi.php, which will include the file again, and that's when it happens.
http://www.php-fig.org/psr/psr-4/
Long story short, while using new \Hi() would fix this, you better not include class files manually, or declare them in paths where they do not belong. Instead declare your files and classes in a proper autoloading compatible fashion, that is for example with a proper namespace in a path that matches that namespace, like
namespace App\Utils;
class Hi {
// ...
}
in
src/Utils/Hi.php
I'm stuck, i wanted to load external library to my symfony2 project but got error stating that class was not found my app/autoloader.php:
...
$loader->add('Tinify', __DIR__.'/../vendor/tinify/tinify/lib');
...
and my file where i want to use it looks like it:
<?php
namespace XYZ\NewsBundle\Controller;
...
use Tinify;
class NewsController extends Controller{
...
public function displayAction($slug)
{
$em = $this->getDoctrine()->getManager();
$external = new \Tinify();
}
error is as follow The autoloader expected class "Tinify" to be defined in file "xyz/app/../vendor/tinify/tinify/lib\Tinify.php". The file was found but the class was not in it, the class name or namespace probably has a typo.
but file under vendor\tinify\tinify\lib\Tinify.php
namespace Tinify;
const VERSION = "1.3.0";
class Tinify {
...
}
i checked if it really has typo but don't see one
Full qualified class name of Tinify is not Tinify but \Tinify\Tinify. Its namespace + classname.
In you NewsController class you should do:
use \Tinify\Tinify;
Also note the backslash at the beginning of the namespace.
Then in the code you should use just class name and not namespace so also change this:
$external = new \Tinify();
to this:
$external = new Tinify();
Why don't install Tinyfy throught Composer?
composer require tinify/tinify
In this way composer handles de autoload of the library, you don't need to load manually nothing, you only must to make an instance of the class and run
$tinify = new Tinify();
I encountered the topic called 'namespace' in php after I started working with Laravel. While trying to understand namespace I found that to extend a class under a namespace, I need to include that class in my current page. Like the following:
directory '..\teacher\Teacher.php'
namespace Teacher;
class Teacher{
public $headTeacher='mr X';
}
to extend the calss i need to include that page as well as use the namespace
directory '..\studnet\student.php'
use \Teacher\Teacher; //use the namespace
include('../teacher/Teacher.php'); // include the page
class mathTeacher extends Teacher{
public function headTeacherName(){
echo $this->headTeacher;
}
}
$student=new mathTeacher();
$student->headTeacherName();
I am wondering how Laravel only use namespace to include classes. Like if I create a controller called 'userController'. The structure of the page is
namespace App\Http\Controllers;
class userController extends Controller{
}
They never included the php page which holds the 'controller' class. But they were able to extend it somehow. Also I can use "View" ,"Auth" just by using the use View or use Auth command. How is it done? How can I implement the same with the code I have provided? Thanks in advance.
Laravel uses composer.php for autoloading the classes. All classes in the autoload directory will be pre loaded. So you can just use the namespace and consume anywhere across the application.
Learn more about composer, composer config can be found on composer.json in your root path for the application
I created a new directory at root 'components'. Then I put a file 'ClassName.php' into this folder. Declare a namespace namespace components; and the class named ClassName Now I try to use it like
$c = new app\components\ClassName()
But there's an error. It says that Class 'components\ClassName' not found.
Where am I missing? I suppose that I should add folder components in include_path or something like that. Please help to understand.
I found the solution.
Just add
Yii::setAlias('components', dirname(dirname(\__DIR__)) . '/components');
In className.php:
namespace components;
Then usage:
$c = new components\ClassName();
This is how you can create custom components in Yii2 (basic application)
Create a folder named "components" in the root of your application.
Then create a class for your component with proper namespace and extend Component class:
namespace app\components;
use yii\base\Component;
class MyComponent extends Component {
public function testMethod() {
return 'test...';
}
}
Add component inside the config/web.php file:
'components' => [
// ...
'mycomponent' => [
'class' => 'app\components\MyComponent'
]
]
Now you can access your component like this:
Yii::$app->mycomponent->testMethod();
In ClassName.php:
namespace app\components;
Added
When you create new ClassName instance, don't forget the leading backward slash for namespace (AKA fully qualified namespace), if your current namespace is not global, because in that case namespace will be treated as relative (Like UNIX paths), use:
$c = new \app\components\ClassName(); //If your current namespace is app\controllers or app\models etc.
$c = new app\components\ClassName(); //If your current namespace is global namespace
You can read more about namespaces basics in PHP documentation
It should be late but I guest my solution may help some one later. I had the same issue and the resolved it the way bellow:
If you want to autoload (import) a customer class in your app, you to do:
create your class where ever you want e.g in my case, i created common/core/Utilities.php
then you have to create an alias (alias is a short cut name you give to your folder path). In my case in create an alias for my folder core (note i should also create an alias for my component folder) e.g
Yii::setAlias('core', dirname(DIR).'/core');
this snippet i put it in my common/config/boostrap.php file. because yii2 load this file at running time.
Now you are ready to use your customize class where ever you want. Just do
$utilities = new \core\Utilities();
Hopefully this may !!!!!!!