Laravel: Hooking up a service - php

So I've implemented a service structure that a stackoverflow user suggested to me in this post. I've got it mostly working but I'm running into the error:
Class 'App\Services\Mailer\Facades\Mailer' not found
My service folder structure looks like this:
app
| App
| | Services
| | | Mailer
| | | | Mailer.php
| | | | MailerFacade.php
| | | | MailerServiceProvider.php
Each of the files in the Mailer directory are namespaced as:
<?php namespace App\Services\Mailer;
Except for the Facade which is namespaced as the following per the example in this blog:
<?php namespace App\Services\Mailer\Facades;
I put a test method in my Mailer.php file's Mailer class:
<?php namespace App\Services\Mailer;
//base service class
class Mailer {
public function sayHi(){
return "hello!";
}
}
I then created the facade:
<?php namespace App\Services\Mailer\Facades;
// Facade for Mailer
use Illuminate\Support\Facades\Facade;
class Mailer extends Facade {
protected static function getFacadeAccessor(){ return 'mailer'; }
}
Then I created the Service Provider to hook them all together:
<?php namespace App\Services\Mailer;
// Mailer's service provider
use Illuminate\Support\ServiceProvider;
class MailerServiceProvider extends ServiceProvider {
public function register(){
$this->app['mailer'] = $this->app->share( function ($app){
return new App\Services\Mailer\Mailer;
});
$this->app->booting( function (){
$loader = \Illuminate\Foundation\AliasLoader::getInstance();
$loader->alias('Mailer', 'App\Services\Mailer\Facades\Mailer');
});
}
}
THe loader for the facade is pointing to the correct namespace, 'App\Services\Mailer\Facades\Mailer', but when I try calling the method in one of my controllers like so:
public function showMe(){
return Mailer::sayHi();
}
I get the message I noted at the top.
I tried putting the facade into a subfolder of the Mailer directory called Facade so that the namespace and folder structure matched exactly, but I got the same error.
I read and re-read the example, the original stackoverflow post, the composer documentation on psr-4 to make sure I wasn't referencing anything incorrectly, and I can't seem to figure it out.
Can anyone point me in the right direction?
EDIT:
So I took a step back and created a vanilla laravel project and tried to add in a service the same way I'm trying in my main project. It's running into a similar error.
Here's a screen shot of every file involved:
Process:
I created my new laravel project
I created my App/Services/Greetings directory structure
I added my psr-4 load path to my composer.json file
I created my underlying class Greetings
I Created a GreetingsFacade class that returns the string 'greetings' for the `getFacadeAccessor method
I created a Greetings Service Provider class GreetingsServiceProvider and added
the register method with it's commands
I added my service provider to the app/config/app.php file in the providers array
I added a route that returns a closure that uses my new Greetings service
I then ran composer dump-autoload and loaded my route
When I load my page I get the error "Class 'App\Services\Greetings\App\Services\Greetings\Greetings' not found" :(

psr-4 expects your directory structure to reflect the namespace structure.
In order to autoload a class App\Services\Mailer\Facades\Mailer, it will look for the file App/Services/Mailer/Facades/Mailer.php.
Additionally, the facade accessor mailer (thus also the IoC-Container slug mailer) is already used by Illuminate\Support\Facades\Mail.
Try something different like my_mailer:
<?php namespace App\Services\Mailer\Facades;
// Facade for Mailer
use Illuminate\Support\Facades\Facade;
class Mailer extends Facade {
protected static function getFacadeAccessor(){ return 'my_mailer'; }
}
and
<?php namespace App\Services\Mailer;
// Mailer's service provider
use Illuminate\Support\ServiceProvider;
class MailerServiceProvider extends ServiceProvider {
public function register(){
$this->app['my_mailer'] = $this->app->share( function ($app){
return new App\Services\Mailer\Mailer;
});
$this->app->booting( function (){
$loader = \Illuminate\Foundation\AliasLoader::getInstance();
$loader->alias('Mailer', 'App\Services\Mailer\Facades\Mailer');
});
}
}

According to your directory structure:
app
| App
| | Services
| | | Mailer
| | | | Mailer.php
| | | | MailerFacade.php
| | | | MailerServiceProvider.php
Your classes namespaces must be:
Service
<?php namespace App\Services\Mailer;
class Mailer {}
Service Provider
<?php namespace App\Services\Mailer;
class MailerServiceProvider {}
Facade
<?php namespace App\Services\Mailer;
class MailerFacade {}
And you autoloader:
"autoload": {
"psr-4": {
"App\\": "app/App"
},
},
For it to work the way you are trying to do, your directory structure would have to be
app
| App
| | Services
| | | Mailer
| | | ├── Facades
| | | | └── Facade.php
| | | | Mailer.php
| | | | MailerServiceProvider.php
EDIT:
In your Greetings namespace, change from:
return new App\Services\Greetings\Greetings;
to
return new Greetings;
And it should work because they are in the same namespace. For an easy reading of the code, add
use App\Services\Greetings\Greetings;
In the top of your .php file.

Related

Laravel Controller does not exists

Im starting to programming in Laravel and trying to understood how the routes works. But it always said that the class "UserControler" that I just created it doesn't exist and I don't know why.
Routes > web.php
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/user',[UserController::class, 'index']);
I have this in the controllers directory that I just made with the artisan.
app>http>controller>UserController.php
<?php
namespace App\Http\Controllers;
class UserController extends Controller
{
public function index()
{
return "Hello World!";
}
}
I get this error:
BindingResolutionException
PHP 8.1.4
9.9.0
Target class [UserController] does not exist.
You forgot to import the controller to your route files. Currently your web.php file can't resolve UserController class, because it doesn't know what it is. You can import it using the use keyword:
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController; //This line
just add your class namespace lik:
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/user',[UserController::class, 'index']);
what zlatan posted was exactly what i forgot too.... It's so obvious to declare it that i didn't see it anymore...
so make sure you declare use App\Http\Controllers\UserController; in the web.php file.

Why am I getting this error: "class app\Laptop not found?"

I am trying different methods to resolve it for 5 hours but can't may any method work.
This is my web.php file:
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', 'LaptopController#show');
This is Laptop.php(Model):
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Laptop extends Model
{
//
}
This is LaptopController.php (Controller):
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use app\Laptop;
class LaptopController extends Controller
{
public function show(){
$laptop=Laptop::all();
echo $laptop->name;
}
}
Inside the controller you are using
use app\Laptop;
but instead it should be
use App\Laptop;
In addition to this there is the problem that you are trying to access name of a Collection: if you want just the first one you should do Laptop::first()

Namespace Alias in Laravel

I apologize if this is duplicate; please guide me to the right directions.
I know we can create class aliases in Laravel from /config/app.php. However trying to create namespace aliases using the same method fails.
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| This array of class aliases will be registered when this application
| is started. However, feel free to register as many as you wish as
| the aliases are "lazy" loaded so they don't hinder performance.
|
*/
'aliases' => [
...
/*
* My custom namespace aliases
*/
'MyNamespace' => 'App\Models\MyNamespace',
],
Testing this in thinker returns the following results:
>> new \MyNamespace\MyClass();
PHP Fatal error: Class 'MyNamespace/MyClass' not found in Psy Shell code on line 1
Do you know a way to create namespace alias in Laravel?
Make your code PSR-4 compatible and put it in composer.json
"autoload": {
"psr-4": {
"MyNamespace\\": "src/MyNameSpace",
}
},
Then run composer dumpautoload. So long as you stick to the convention of subfolders being namespaces, your classes will autoload.
src/MyNamespace/SomeClass.php would have namespace MyNamespace; and class SomeClass.
src/MyNamespace/Something/SomethingElse.php would have namespace MyNamespace\Something; and class SomethingElse.

"Target [App\Http\Controllers\Controller] is not instantiable."

I'm trying to follow laracasts tutorial on laravel fundamentals but after getting composer and laravel installed with no problems I can't get my routes file to work with the controller I've reinstalled laravel copied it exactly how laracasts has his but still nothing, anyone see anything wrong with these two files?
routes.php files
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
Route::get('/', 'Controller#index');
Route::get('contact', 'Controller#contact');
controller.php file
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
abstract class Controller extends BaseController
{
use DispatchesJobs, ValidatesRequests;
public function ___construct()
{
$this->middleware('guest');
}
public function index()
{
return 'hello world!';
}
public function contact()
{
return 'Contact me!';
}
}
I have it hosted on localhost:8888 using phps server command if that is any help.
The reason might be that your controller class is abstract, hence it's not instantiable. Remove the abstract keyword.
if your route is get or post and actually you have implemented resource, so you get this type of error

Laravel 5 Fatal Error: class not found exception cannot access the model classes when it is inside a folder

Here is my application structure,
my-first-app
|
|-app
|
| -Commands
| -Console
| -Events
| -Http
| -models(custom define folder)
|
|-Base(folder)
| |
| | -StuDetails.php
| | -StuDetailsQuery.php
|
|-Map(foder)
|-StuDetails.php
|-StuDetailsQuery.php
Actually I'm using propel ORM to retrieve data from the database.
I created my model classes inside the folder models.
Then I tried to access StudetailsQuery class inside my pageController class which is inside http folder extended as Controller.
Here it is :
<?php
namespace App\models\propel;
namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Base\StuDetailsQuery;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\View;
class pagesController extends Controller
{
public function index()
{
$stu= StuDetailsQuery::create()->find();
return view('pages.index', compact('stu'));
}
But I get error :
PHP Fatal error: Class 'Base\StuDetailsQuery' not
found in
/var/www/my-first-app/app/Http/Controllers/pagesController.php
I tried;
composer dump-autoload
adding following lines to composer.json file
"autoload": {
"psr-4":{
"propel\": "app/models/propel/"
}}
but nothing goes fine for me.. Any suggestions please ??
"autoload": {
"classmap": [
"database",
"app/models/propel"
]
this solved my problem... :)
I keep getting similar missing class errors. Although I follow the laracast autoloading examples in You Must Use Composer laracast completely (including the modification of composer.json), I get stuck with a missing class error.
In watching the videos I notices jeffery way uses a \ occasionally before the object name..... I don't know why but in frustration I added it, and it worked for me.
In summary I find I have to use a "\" before the object, like this:
new \Bar;
I hope this helps, and if someone can help me understand what is going on please let us know.

Categories