I am starting to play with symfony4. I've just created new application and create new LuckyController. It works with routes.yaml configured in this manner:
lucky:
path: /lucky/number
controller: App\Controller\LuckyController::number
With the following controller:
<?php
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
class LuckyController
{
public function number()
{
return new Response('<html><head></head><body>' . rand(111, 999) . '</body></html>');
}
}
But I want to use annotations. So I decided to comment routes.yaml. Following documentation that explain how to create a route in symfony I've made this:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class LuckyController extends Controller
{
/**
* #Route("/lucky/number")
*/
public function number()
{
return new Response('<html><head></head><body>' . rand(111, 999) . '</body></html>');
}
}
Sometimes this problem occurs because of cache.you need to run php bin/console cache:clear.then it will work fine.
In Symfony4 you have to install annotations bundle.
Run this command composer require annotations
Then restart Your project.
I had the same thing when trying the annotations, then I found out with the demo installed (the blog) you need to add the language in the URL. So the documentation says:
http://localhost:8000/lucky/number will work exactly like before
That did not work. This however did:
http://localhost:8000/en/lucky/number
As suggested in #Jack70 answer.
https://127.0.0.1:8000/en/random/number
This should work.
If you run the command php bin/console debug:router it would show you the list of routes available as you can see in that list, you need to add the locale (language) as first argument.
app_annotationsample_number ANY ANY ANY /{_locale}/random/number
If you use annotations - you need check config/routes/anotations.yaml.
You need check path to your controller or add new path, for example:
controllers:
resource: ../../src/Controller/
type: annotation
Also, you'll get that error if the route name appears more than once.
I ran into that error while developing Angular app, so in order to debug I tried that same route in Postman, which I knew used to work fine, but this time it did not throwing the mentioned error. Luckily, I have just added one new controller, so finding the culprit was easy: the problem was that after copying methods from web controller to api controller I forgot to change route name in one of the methods.
So you might wanna be careful when copying :)
Related
I am using PHP 7.4.1 and Laravel Framework 6.20.16.
I am trying to implement the following library: telegram-bot-sdk and the following version "irazasyed/telegram-bot-sdk": "^2.0",
After installing the sdk and getting my private token from telegram's #botfather. I am trying to use the sdk.
I created a route and a controller:
route
Route::get('telegramHello', 'TelegramController#getHello');
controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Telegram\Bot\Api as Telegram;
use App\Helpers\TelegramResponse as Response;
class TelegramController extends Controller
{
public function getHello() {
$api = new Telegram(); // ----> HERE I GET THE ERROR
$response = $api->getMe();
return Response::handleResponse($response);
}
//...
When opening my route I get the following exception:
The thing I do not understand is that I have created the config telegram.php and loading my correct token from my .env file:
In my .env file it looks like the following:
Any suggestions what I am doing wrong?
I appreciate your replies!
Use Facade, not original API class. Your config is correct, you just using wrong class.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Telegram\Bot\Laravel\Facades\Telegram;
use App\Helpers\TelegramResponse as Response;
class TelegramController extends Controller
{
public function getHello() {
$response = Telegram::getMe();
return Response::handleResponse($response);
}
//...
Also i may recommend you using westacks/telebot instead of irazasyed/telegram-bot-sdk. I created it as irazasyed's was poorly documented and really buggy at a lot of places.
The two comments above helped me the most:
Use "" for your TELEGRAM_BOT_TOKEN
Instead of using your own named .env variable use TELEGRAM_BOT_TOKEN
I hope this works also for others that have this problem.
I have started building a new Web App using Symfony, but am having issues using classes.
PhpStorm is able to find the functions within the classes (due to the fact that it gives suggestions when you type $className->.
Also, to prove this is not the same as the other similar questions, I have over simplified it, and even so, the error still occurs.
I have the below in my DefaultController:
<?php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use testBundle;
use AppBundle\domainionClasses\firstlevelchecks;
class DefaultController extends Controller
{
/**
* #Route("/register",name="register")
*/
public function registerAction(){
$testClass = new firstlevelchecks();
$testing = $testClass->donothing(); //the IDE knows that the function donothing() exists, in fact it suggests it.
return new Response('');
}
}
The below is the php class located in AppBundle/domainionClasses/test1.php
<?php
namespace AppBundle\domainionClasses;
class firstlevelchecks
{
function donothing(){
return null;
}
}
When loading the /register route, the below Symfony error is displayed:
Attempted to load class "firstlevelchecks" from namespace "AppBundle\domainionClasses".
Did you forget a "use" statement for another namespace?
It is attempting to load the class from the correct name space, and I have used a use statement.
Is there anything I am missing here, or is there a problem with Symfony? This is the first time I used the new version of PhpStorm, and have just downloaded the plugin, also the first time I have experienced this issue :(
Because your file is named test1.php, how can the autoloader know which file to include ?
You shoud rename it to firstlevelchecks.php (= the name and case of your class).
I'm on Laravel 5, I'm trying to integrate SAML 2.0 with it. I've found this package = https://github.com/aacotroneo/laravel-saml2
I tried follow their steps, but at the end when I use
<?php
namespace App\Http\Controllers;
class SAMLController extends Controller {
public function adminSignIn(){
return Saml2::login(URL::full());
}
}
I've already added
provider
'Aacotroneo\Saml2\Saml2ServiceProvider',
aliases
'Saml2' => 'Aacotroneo\Saml2\Facades\Saml2Auth',
Why do I still get this error?
Class 'App\Http\Controllers\Saml2' not found
Note : I've even retry after sudo composer dumpauto, same result.
You need to use full namespace for the facade:
\Saml2::login(URL::full());
Or add this to the top of the class:
use Saml2;
you need to explicitly write "use" on top
use Saml2;
This might work.
I'm asking/answering because I have had so much trouble getting this working and I'd like to show a step-by-step implementation.
References:
https://laravel.com/docs/5.0/facades#creating-facades
http://www.n0impossible.com/article/how-to-create-facade-on-laravel-51
This may not be the only way to implement facades in Laravel 5, but here is how I did it.
We're going to create a custom Foo facade available in the Foobar namespace.
1. Create a custom class
First, for this example, I will be creating a new folder in my project. It will get its own namespace that will make it easier to find.
In my case the directory is called Foobar:
In here, we'll create a new PHP file with our class definition. In my case, I called it Foo.php.
<?php
// %LARAVEL_ROOT%/Foobar/Foo.php
namespace Foobar;
class Foo
{
public function Bar()
{
return 'got it!';
}
}
2. Create a facade class
In our fancy new folder, we can add a new PHP file for our facade. I'm going to call it FooFacade.php, and I'm putting it in a different namespace called Foobar\Facades. Keep in mind that the namespace in this case does not reflect the folder structure!
<?php
// %LARAVEL_ROO%/Foobar/FooFacade.php
namespace Foobar\Facades;
use Illuminate\Support\Facades\Facade;
class Foo extends Facade
{
protected static function getFacadeAccessor()
{
return 'foo'; // Keep this in mind
}
}
Bear in mind what you return in getFacadeAccessor as you will need that in a moment.
Also note that you are extending the existing Facade class here.
3. Create a new provider using php artisan
So now we need ourselves a fancy new provider. Thankfully we have the awesome artisan tool. In my case, I'm gonna call it FooProvider.
php artisan make:provider FooProvider
Bam! We've got a provider. Read more about service providers here. For now just know that it has two functions (boot and register) and we will add some code to register. We're going to bind our new provider our app:
$this->app->bind('foo', function () {
return new Foo; //Add the proper namespace at the top
});
So this bind('foo' portion is actually going to match up with what you put in your FooFacade.php code. Where I said return 'foo'; before, I want this bind to match that. (If I'd have said return 'wtv'; I'd say bind('wtv', here.)
Furthermore, we need to tell Laravel where to find Foo!
So at the top we add the namespace
use \Foobar\Foo;
Check out the whole file now:
<?php
// %LARAVEL_ROOT%/app/Providers/FooProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Foobar\Foo;
class FooProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
$this->app->bind('foo', function () {
return new Foo;
});
}
}
Make sure you use Foobar\Foo and not Foobar\Facades\Foo - your IDE might suggest the wrong completion.
4. Add our references to config/app.php
Now we have to tell Laravel we're interested in using these random files we just created, and we can do that in our config/app.php file.
Add your provider class reference to 'providers': App\Providers\FooProvider::class
Add your facade class reference to 'aliases': 'Foo' => Foobar\Facades\Foo::class
Remember, in aliases, where I wrote 'Foo', you will want to put the name you want to reference your facade with there. So if you want to use MyBigOlFacade::helloWorld() around your app, you'd start that line with 'MyBigOlFacade' => MyApp\WhereEverMyFacadesAre\MyBigOlFacade::class
5. Update your composer.json
The last code change you should need is to update your composer.json's psr-4 spaces. You will have to add this:
"psr-4": {
"Foobar\\" : "Foobar/",
// Whatever you had already can stay
}
Final move
Okay so now that you have all that changed, the last thing you need is to refresh the caches in both composer and artisan. Try this:
composer dumpautoload
php artisan cache:clear
Usage & A Quick Test:
Create a route in app/routes.php:
Route::get('/foobar', 'FooBarController#testFoo');
Then run
php artisan make:controller FooBarController
And add some code so it now looks like this:
<?php
namespace App\Http\Controllers;
use Foobar\Facades\Foo;
use App\Http\Requests;
class FooBarController extends Controller
{
public function testFoo()
{
dd(Foo::Bar());
}
}
You should end up with the following string:
Troubleshooting
If you end up with and error saying it cannot find the class Foobar\Facades\Foo, try running php artisan optimize
The Laravel documentation clearly describes how to change your routes if you nest your controllers in folders. It seems REALLY simple, and yet I'm still getting an error. Here's the error:
"Class App\Http\Controllers\Input\InputController does not exist"
^That path looks 100% correct to me. What gives?
File Structure:
-Controllers
--Auth
--Input
---InputController.php
Routes:
Route::get('input', 'Input\InputController#getInput');
InputController:
<?php namespace App\Http\Controllers;
use Illuminate\Http\Response;
class InputController extends Controller
{
public function getInput()
{
return response()->view('1_input.input_form');
}
}
Thanks for any help!
Change Controller namespace from
namespace App\Http\Controllers
to
namespace App\Http\Controllers\Input
namespace needs to be changed to the directory your controller is in 'App\Http\Input'
You need to pull in Controller with use App\Http\Controllers\Contoller so that you can extend it.
<?php
namespace App\Http\Controllers\Input;
use App\Http\Controllers\Controller; // need Controller to extend
use Illuminate\Http\Response;
class InputController extends Controller
{
public function getInput()
{
return response()->view('1_input.input_form');
}
}
you should try running a couple commands in your base dir from your terminal (shell/prompt):
composer dump-autoload
or if you don't have composer set as executable:
php composer dump-autoload
and then:
php artisan clear-compiled
This way your laravel would prepare everything again "from scratch" and should be able to find the missing controller class.
Basically laravel generates some additional files to boot up faster. If you define a new class it doesn't get included into that "compiled" file. This way your class should be "introduced" to the framework.