Namespacing and autoloading in Laravel - laravel

This might be a simple question but I'm wondering how do I autoload useful classes without declaring use statements on every single file.
<?php namespace App\Http\Controllers;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Input;
class HomeController extends Controller
{
public function index()
{
Input::get('query');
}
}
If I remove the use Illuminate\Support\Facades\Input; line I will get a class not found error because I'm using the Input class.
Is there a way to autoload useful classes like Input, Response, View like in Laravel 4. What's the point of the Aliases in app.php?

You can import input class using both:
use Illuminate\Support\Facades\Input;
or
use Input;
then you can use Input::get('query'); code. That's how PHP namespaces work - you can also look at How to use objects from other namespaces and how to import namespaces in PHP for more details about it.
If you don't use use statement for importing class, you can use \Input::get('query'); or \Illuminate\Support\Facades\Input::get('query');.
Aliases allow you not to use fully qualified classes for example \Illuminate\Support\Facades\Input but shorter form \Input. That's why I showed above 2 versions - the shorter one uses aliases and the longer uses full class path. The same mechanism is both in Laravel 4 and Laravel 5 I believe.

The problem is not really in Laravel, but in PHP. When you namespace a class, it assumes that everything inside that class will be in the same namespace, so you have to tell it that, for a particular class, you need it to use a different namespace.
You can use them by referring to the root namespace, like this:
class HomeController extends Controller
{
public function index()
{
\Input::get('query');
}
}

Related

Basic OOPS concept needs clarification

I am new to OOPS and MVC hence, have confusion about certain concepts which I would like to clarify. As mentioned below in the code, I think, namespace App\Http\Controllers\Admin; that is mentioned corresponds to the directory structure and thus means the class AdminController is contained in Admin folder as is pointed there. But then we have the use keyword inorder to use the following namespace. Now the question is why do we use use App\Http\Controllers\Controller;, particular line. What purpose does it serve?
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
class AdminController extends Controller
{
public function index()
{
echo "admin controller";
}
}
namespace App\Http\Controllers\Admin; as you stated is used to let laravel know where to access your AdminController from.
And your AdminController which extends the base Controller uses the default classes of base Controller so we need to use the use specification. use App\Http\Controllers\Controller; is used to let declare that you are going to use the base Controller classes in your AdminController.
For more info read the official laravel docs.
use usually allows a developer to shorten the namespace.
It copies another class from same or different namespace so you can use that class in your code with its class name. You need to write the full namespace if you will use another class without use.
This might help you understand it better. https://daylerees.com/php-namespaces-explained/
namespaces basically group your functions, classes and constants under a particular 'name', which we call a namespace.
Now use keyword allows a developer to shorten the namespace.use is useful when we are going to call the same function again and again in the same code file or call different functions, constants or classes under a particular namespace.

Codeigniter Model extends CI_MODEL

I have a problem,
I want to create 2 different model extends CI_Model in core folder
for example
class MY_FirsModel extends CI_Model {
}
class MY_SecondModel extends CI_Model {
}
is it posible when using codeigniter
thank you
According to Codeigniter's Documentation, when extending a core class, you need to give the same name to your class, only changing CI_ by MY_.
When the loader class is fetching all core classes it looks for specific matching names such as Model, Controller, Exceptions and so on. It starts looking by the application/core folder, with prefixes MY_ and then goes to system/core if a extended class was not found.
If you need to maintain the names MY_FirsModel and MY_SecondModel, you can create these models in the application/libraries folder and the require these files in the classes you will use them.
require_once APPPATH.'libraries/MY_FirsModel.php';
and
require_once APPPATH.'libraries/MY_SecondModel.php';
it is possible to have it like that way. This will going to work. I read it once on CI forum (I don't remember the exact link as it's been long time) that some admins like to use this kind of style but many people are in favor of separating them into 2 different file

Composer package - use custom model if exists

My apologies if this exists already but my search-fu can not find the answer.
I have a composer package, and want to use my model ONLY IF an existing model doesn't exist (or extend the custom model), but I can't seem to figure out how to specify the "use" command properly inside my composer model. Since I won't know the name of the "app" using the package, I can't extend it.
<?php
namespace MyComposer\Package\Models;
use Illuminate\Database\Eloquent\Model;
class MyPackageModel extends Model
{
If I put it as a config option, I can't use that in the extends i.e class MyPackageModel extends config('custom_model_name')
I had thought I should do the check in the ServiceProvider but I can't seem to find the right code to register the proper model name to use in there.
Thanks.
I've done something similar to this before, I believe. But my approach was slightly different. See if it makes sense:
Create a base class in your own package. This will be the fallback
model which will be used if the "local" package (the one consuming
your package) doesn't have it's own version of it;
Create a config file which states which model will be used. The default is the model inside your own package (i.e. the fallback);
After installing and setting up your package, if a user does nothing they will automatically have your base model available. If they wish to override your base model with a custom local version, they can simply extend your base model and alter the model to be used in their config file.
I've also found that sometimes it's useful for the base model to 1) implement an interface that can be checked in your package's logic without relying on a specific class (which, after all, is meant to be overridden, right?); and 2) have most of it's logic inside a trait which the "local" model can use without ever having to extend your model (crucial if the local model already extends some other class for whatever reason).
How you approach the code would very much depend what you plan to do with that model. Say, for example, you have a supporting class that creates media entries in your database. Here's your packages model:
<?php
namespace Namespace\Package;
class Media
{
//...
}
And here's the default config:
<?php
return [
'model' => \Namespace\Package\Media::class,
];
And here's a sample manipulation, where you actually account for the local app to override your own model:
<?php
namespace Namespace\Package;
class MediaManager
{
protected function getModel()
{
$model = config('package.model');
return new $model;
}
public function createMedia($attributes = [])
{
$media = $this->getModel($attributes);
$media->save();
return $media;
}
}
That is to say, you never reference any Media model literally. You do your manipulations via the MediaManager. Of course the logic is very simplistic, but hopefully it's enough to get the bigger picture.

Class App/Http/Controllers/View Not Found error

I am new to laravel 5 and currently stumped by this error:
FatalErrorException in TicketController.php line 18: Class 'App\Http\Controllers\View' not found
Weird thing is the view does in fact exist, i checked to see if the route was indeed routing to the right controller and it was, the error pops up when i try to do this:
return View::make('tickets.bus.index');
It's either i am making some mistake somewhere or if the implementation is different from laravel 4
The problem is not the actual view but the class View. You see when you just reference a class like View::make('tickets.bus.index') PHP searches for the class in your current namespace.
In this case that's App\Http\Controllers. However the View class obviously doesn't exists in your namespace for controllers but rather in the Laravel framework namespace. It has also an alias that's in the global namespace.
You can either reference the alias in the root namespace by prepending a backslash:
return \View::make('tickets.bus.index');
Or add an import statement at the top:
use View;
In Laravel 5.1 the correct use code would be:
use Illuminate\Support\Facades\View;
There exists a helper-function, view(), which is in the global namespace, and may be used to simplify the syntax:
return view('tickets.bus.index');
With this method, it is unnecessary to include use View; or include the root namespace, e.g., \View.
The concepts that lukasgeiter explained are essential to understanding Laravel, even if you elect to use the helper-function.
For me it was namespace problem. I used php artisan to create controller but it seems like php artisan used different namespace (may be I have to change something in composer.json to fix it but I am totally new in laravel)
Whoops, looks like something went wrong.
FatalErrorException in PagesController.php line 11:
Class 'App\Http\Controllers\Controller' not found
Good that I am using phpStorm which automatically inserted proper namespace
make sure you check out namespace properly. This is how I had controller created with php artisan
namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller; //php artisan inserted.
class PagesController extends Controller
{
public function index(){
return view('index');
}
public function about(){
return view('pages.about');
}
}
and this is how phpstorm inserted after I manually wrote extends controller
namespace App\Http\Controllers;
use App\Http\Requests;
use Illuminate\Routing\Controller; //I manually wrote extends Controller and selected this namespace
class PagesController extends Controller
{
public function index(){
...
There exists a helper-function, view(), which is in the global namespace, and may be used to simplify the syntax:
return view('tickets.bus.index');
With this method, it is unnecessary to include use View; or include the root namespace, e.g., \View.
The concepts that lukasgeiter explained are essential to understanding Laravel, even if you elect to use the helper-function.

laravel - namespacing controllers and models - lot of code repetition

Here is the example of beginning of my TurnoverController
namespace App\Controllers;
// libraries
use \Turnover\Form;
use \Turnover\StatsByEventNames;
use \Utilities\Utils;
// models
use \Card;
use \GameClient;
use \Gametypes\Dogs;
use \Manager;
// Facades
use \Session;
use \App;
use \URL;
class TurnoverController extends BaseController
Since PSR standard says every class should be in a namespace of at least one level, I added namespace.
But now to load just simple models, without namespace yet, I always have to call use
\ModelName
Plus also same for things like Session, App, Etc.
And also there is a plan to have models in a namespace
App\Models
So to use a model then will have to write
use App\Models\ModelName
. Without namespaces all this was automatic - controllers knew where the models and Facades are. How can I fix that so at least models in default model folder would not required to call use statement?
Same for Facades.

Resources