I was going through socialite tutorial which is created by Laravel 5 and I'm using Laravel 5.1 and I saw that there is a file in tutorial like AuthenticateUser.php in repositories folder. But repositories folder doesn't even exist in Laravel 5.1. Where I should create a file AuthenticateUser.php in Laravel 5.1?
Laravel uses composer's autoloading, so it doesn't matter where you store your files, so long as their autoloading mechanism is defined in the composer.json file. Laravel 5 apps start with this defined in their composer.json:
"psr-4": {
"App\\": "app/"
}
So if you created a directory at app/Repositories, you could create a file in it that looked like this:
<?php namespace App\Repositories;
class MyRepository {
public function doSomething() {}
}
Then you can reference it in the rest of your application like this:
<?php namespace App\Http\Controllers;
use App\Repositories\MyRepository;
use Illuminate\Routing\Controller as BaseController;
FooController {
protected $repo;
public function __construct(MyRepository $repo)
{
$this->repo = $repo;
}
public function someAction()
{
return $this->repo->doSomething();
}
}
Composer will load the file for you, so long as you've defined a mechanism for doing so.
Related
I have created some library services in app\Library. I used AppServiceProvider to bind that service using following code:
$this->app->bind('App\Library\Globalfunction', function ($app) {
return new Globalfunction();
});
app\Library\Globalfunction.php
<?php
namespace App\Library;
class Globalfunction {
protected $_ci;
public $siteConfig=array();
public $smtpConfig=array();
public $socialConfig=array();
public $paramConfig;
public $paramFrom;
public function test($param) {
return $param;
}
}
?>
To use this test() in controller i am including namespace using following:
use App\Library\Globalfunction;
once namespace is included i use following code:
$globalFunction = new Globalfunction();
echo $globalFunction->test('hello');
All of this code working fine but i don't want to add use App\Library\Globalfunction; in each file so is there anyway i can do that? is there any autoload file where i can put this and i can access Globalfunction?
I google solution for that and i tried several solutions like add this in composer or create package etc but it's not working so please if anyone have solution for this problem please let me know.
Maybe you can follow the same approach as Laravel?
Let me give you an example on how to achieve this.
First, create a Helpers.php file in app/Helpers.php.
You also need to autoload it.
"autoload": {
"classmap": [
"database/seeds",
"database/factories",
"database/providers"
],
"files": [
"app/Helpers.php"
],
"psr-4": {
"App\\": "app/"
}
}
Once that is done, you could define a function as such in your newly autoloaded Helpers.php:
if(! function_exists('global_function')) {
function global_function()
{
return new \App\Library\Globalfunction();
}
}
Then to use it anywhere, you can just do this.
global_function()->test('hello');
This is just a simple example. Obviously there are a lot of considerations you have to make before implementing this.
However, Laravel has a similar approach to providing global helper functions. For example:
use Illuminate\Support\Facades\Session;
// This
echo Session::get('key');
// is the same as
echo session()->get('key');
I created a new folder in the directory app which is called Services. So the directory of Services is app/Services. I want to use now a file of Services called Connection.php in a Controller app/Http/Controllers but when I try that, I get following error:
Class App\Services\Connection does not exist
I also tried to add the directory and file in my composer.json but this didn't fixed it either.
Controller:
namespace App\Services;
namespace App\Http\Controllers;
use App\Services\Connection;
use Illuminate\Http\Request;
class ExampleController extends Controller
{
protected $conn;
public function __construct(Connection $conn)
{
$this->conn = $conn;
}
Composer.json
"autoload": {
"classmap": [
"database",
"app/Services"
],
"autoload-dev": {
"classmap": [
"tests/TestCase.php",
"app/Services/Connection.php"
]
},
Edit 17.12.2016: (problem not solved yet)
Thanks for all who stick with me so long on this problem! I'm sry, if I gave too less information so I'll sum up few things that I tried.
1 => Deleted the secound namespace App\Services
2 => Added routes(or directory) to my composer.json ( like above )
3 => Used composer updated and composer dump-autoload
4 => Used use App\Services\Connection (the path to my connection class in Services, which I want to use in my ExampleController in App\Http\Controllers\ExampleController)
Connection class:
class Connection
{
//Some guzzle stuff
}
So the ExampleController looks exact as above just without the Services namespace anymore and I get exact the same error. What am I doing wrong?
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Contracts\Auth\Guard;
use App\Http\Controllers\Controller;
use App\Services\Connection;
class ExampleController extends Controller
{
public function __construct(Guard $auth, Connection $conn)
{
$this->auth = $auth;
$this->conn = $conn;
}
}
Please try to use this code.
Presented this solution as a comment but to make it easier for future viewers:
The solution to this is to ensure that proper name spacing is in all files being referenced including the controller and the classes. If the namespace isn't correct it won't be able to access it.
In this case you have to make sure that the namespace for the Connection class was using App\Services as the namespace and that the controller accessed it in the same namespace of App\Services\Connection.
The error is on your namespace declaration. you are declaring two namespaces for the same class!
namespace App\Services;
namespace App\Http\Controllers;
The last one will be used.
Remove the App\Http\Controllers namespace line.
Also remember that you should import the base controller:
use App\Controllers\Controller;
Why?
When you try to use App\Services\ExampleController, composer will look for that class in the autoload paths, but since your namespace is different, it will not be able to load it.
Hi can anyone clarify this for me. I have a rather large Laravel 4 app using a few models. I would like to upgrade to L5 and would simply like to use the same model calls in the controllers.
e.g.
Course::
\Course:: //if controller in a deeper folder
The course model is in App/Models. I've tried a composer mapping App/Models but to no avail.
Thanks
I don't know about anyone else. But in my installation of Laravel 5, my models are defined directly within the app folder. The app directory is psr-4 namespaced as App.
composer.json
"autoload": {
...
"psr-4": {
"App\\": "app/"
}
}
Models are then defined under the App namespace. e.g.
namespace App;
use Illuminate\Database\Eloquent\Model;
class Course extends Model {
}
So you can either:
1: Use the full path to the model whenever you use it:
\App\Course::all();
2: use your model before using it like you normally would:
namespace Your\Namespace;
use App\Course;
class YourClass {
public function yourFunction()
{
Course::all();
}
}
3: Create a folder called Models, put your models in there and make sure that their namespace reflects the path (And then call the model like in options 1 and 2):
// app/Models/Course.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Course extends Model {
}
e.g.
\App\Models\Course::all();
or
namespace Your\Namespace;
use App\Models\Course;
class YourClass {
public function yourFunction()
{
Course::all();
}
}
That's just how namespaces work. If you specify a class PHP will always search for it relative to the current namespace. Unless you prepend a backslash and use the full path or add an import statement at the beginning of your files:
namespace App\Http\Controllers;
use App\Models\Course;
class ...
Or
\App\Models\Course::all();
I should add that many editors and IDEs are able to automatically resolve and import classes, so with the right tools it's not that cumbersome...
I am trying to load controller that resides inside a package.
Package itself is on the root level in a folder like /packages/my/ ...
The package structure is like this:
/packages/my/framework/src/My/Controllers/PageController.php
Frist in my RouteServiceProvider:
$router->group(['namespace' => 'My\Controllers'], function($router)
{
require "...../routes.php";
});
in the composer.json in the root of laravel
"psr-4": {
"App\\": "app/",
"My\\": "packages/my/framework/src"
}
then composer dump-autoload , i can see its been added to autoload_psr4.php
the actual controller
<?php
namespace My\Controllers;
use App\Http\Controllers;
class PageController extends Controllers\Controller { .... }
But I am getting ReflectionException that the class does not exist. Obviously the routing part works, why it can't see the Controller?
Thanks!
closing my own question .. I was missing the root namespace in the psr-4 loader .. packages/my/framework/src/My
When using a separate class for a model observer, where exactly should I register the observer? The documentation says to call User::observe(new UserObserver); but I’m not sure where the best place to do this would be.
https://laravel.com/docs/5.4/eloquent#observers
Since an observer is just a collection of events you are listening to, I'd say place it where Laravel suggests you place individual events: on the boot method of the model itself.
class User extends Eloquent
{
public static function boot()
{
parent::boot();
User::observe(new UserObserver);
}
}
Where to put the UserObserver class is a little more flexible and depends on how complex it will end up being.
For simple observers
If you can bare having it load every time the app runs, create an app/observers.php file, then put this at the end of your app/start/global.php:
require app_path().'/observers.php';
Alternatively, you can use composer to autoload that one file, by appending your composer.json:
{
"autoload": {
"classmap": [
//...
],
"files": [
"app/observers.php"
]
}
}
For more complex observers
If you plan to have many different observers, I'd say create your own namespace and let Laravel / Composer do the autoloading for you. In order to do that, create a folder like app/MyNamespace/Observers, then place each observer file inside of it (each named exactly like the class -- i.e. UserObserver.php).
Your UserObserver.php class should now look like this:
<?php
namespace MyNamespace\Observers;
class UserObserver
{
public function saving($model)
{
// ...
}
public function saved($model)
{
// ...
}
}
And you'll have to declare the full class whenever you are using it:
User::observe(new MyNamespace\Observers\UserObserver);
Or:
use MyNamespace\Observers\UserObserver;
class User extends Eloquent
{
public static function boot()
{
parent::boot();
User::observe(new UserObserver);
}
}
Finally, edit your composer.json and add your namespace to follow PSR-0 autoloading:
{
"autoload": {
"classmap": [
//...
],
"psr-0": [
"MyNamespace": "app/"
]
}
}
PS: Don't forget to run composer dump-autoload after editing composer.json.