I have two files in the same directory Graph:
IModel.php
DataModel.php
For these files in the top I set namespace as: namespace App\Library\Graph;
When I try to use IModel.php in DataModel.php I do:
namespace App\Library\Graph;
use IModel;
I get response: Interface 'IModel' not found
You need to include the php file and then you will be able to call the class.
require('App\Library\Graph\IModel.php');
$myClass = new IModel();
You can also use an autoloader.. Then include the autoloader and all your classes that are mapped through the autoloader will be able to be called.
Here is a link to read about autoloading using composer.
https://phpenthusiast.com/blog/how-to-autoload-with-composer
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 am trying to use Azure storage for php, the setup steps are to include the namespace, include composer autoload and then use the azure classes, so I have the following. However further down I use the class Microgrid and it's not found because of the namespace, it is in a different directory. How can I use other classes that aren't part of that namespace? Also, what's the correct way to specify your namespace path? It's in a different directory relative to the page this is for and the one I am using is not at the root, should I start at the root?
namespace MicrosoftAzure\Storage;
use \MicrosoftAzure\Storage\Common\ServicesBuilder;
use \MicrosoftAzure\Storage\Blob\Models\CreateContainerOptions;
use \MicrosoftAzure\Storage\Blob\Models\PublicAccessType;
use \MicrosoftAzure\Storage\Common\ServiceException;
require_once '/var/www/html/vendor/autoload.php';
$action = MicroGrid::GetParameter('action');
ClassNames are considered relative to the current namespace unless they start with a \
This means that inside the MicrosoftAzure\Storage namespace you can use the relative namespace for class.
If you want to call a class from a different namespace you should call fully-qualified name for it like
$action = \MicrosoftAzure\WhereEver\MicroGrid::GetParameter('action');
or use the name space or unique class with fully-qualified name
use \MicrosoftAzure\WhereEver;
or
use \MicrosoftAzure\WhereEver\MicroGrid;
then:
$action = MicroGrid::GetParameter('action');
Edited to make it clear
namespaces allow us to avoid naming collisions and to alias long
names caused by avoiding naming collisions.
it depends to your autoloader for a simple example I create a new project and make this autoloader in the index.php located at root directory
function __autoload($className){
//if it's a full name with windows style slashes correct the path
$file_name = str_replace('\\', '/', $className);
require_once("vender/src/".$file_name.".php");
}
when I call $date = new \App\Utility\Date(); autoloader will require this file:
verdor/src/App/Utility/Date.php
and in Date.php I used this name space namespace App\Utility;
PHP does not provides a class autoloader out of the box.
There are many autoloaders for PHP, and the most common autoloader standard is the PSR-4, used by many frameworks and applications.
If you are not using an autoloader, you should require every class file (and recursive dependencies) before using it.
Azure uses Composer Autoloader and PSR-4.
You should use Composer Autoloader on your project, then import your class from the right namespace (you are not importing it on your example code)
A namespace basically groups your classes together. You can use something outside your namespace by explicitly using it e.g.
namespace App;
use Illuminate\Database\Eloquent\Model;
In this case I'm 'grouping' this and other classes in a namespace called 'App' but I want to use 'Model' provided by Eloquent (the Eloquent class having a namespace of 'Illuminate\Database\Eloquent') in this class.
If 'Microgrid' is not part of your current namespace, you'll need to explicitly add its namespace in your 'use' statements.
a quick (maybe stupid) question.
I'm using a namespace for my controllers, like so:
namespace Members;
use DB;
use Input;
use PerformanceReport;
use Redirect;
class AdminController extends MembersController {
And as expected, I have to provide use statements for the Laravel classes I wish to use.
From what I've understood, the composer autoloader prevents this from being necessary if used correctly.
So my question being, is it possible to configure the autoloader to suit my needs, and if so, how would I go by doing this?
Your question is connected with the way PHP namespaces work, not with composer's autoloader.
If your class is in namespace Controllers; and you'd write Redirect::to('/') php would assume that the class you're referring to is in the current declared namespace (in that case Controllers/Redirect). You can either write \Redirect::to('/') or put a use Redirect statement on top like you did.
Composer's autoload just maps namespaces to their file directory (see vendor/composer/autoload_classmap.php for how it maps it).
If you want to dive more into composer's autoloading, i'd recommend read up on PSR-0 and PSR-4.
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
I'm trying to learn the namespaces feature in PHP, however how do I access classes that are in namespaces?
Like, say I have the class Users inside the namespace called Core, how do I access that namespace from the Pages namespace?
I believe this is what you're after:
<?php
$users = new \Core\Users;
echo $users->all();
When you want to use a class that's inside a namespace, you need to define the "absolute path" to the class, like I have done in the example. Note the \ before the Core namespace, that tells PHP to use the Core namespace that is located in the root or "global" namespace of PHP.
So if you wanted to access the Users class in your Pages namespace, you would do the following:
<?php
namespace Pages;
$users = new \Core\Users;
echo $users->all();
There's also another way to use the Users class, which is:
<?php
namespace Pages;
use \Core\Users as Users;
$users = new Users;
echo $users->all();
The use \Core\Users; line allows you to use the Users class from the Core namespace as if it were a normal class inside the Pages namespace.