I'm trying to extend Laravel 5 core class. What i want to achieve is that i can have custom url generators eg. URL::test(), will generate custom link.
So far i have:
Created app/Acme/lib folder
Added app/Acme/lib path to composer.json classmap
"autoload": {
"classmap": [
....
app/Acme/lib
]
}
Created custom UrlGenerator class in Acme/lib/CustomUrlGenerator.php
<?php namespace App\Acme\lib;
use \Illuminate\Routing\UrlGenerator;
class CustomUrlGenerator extends UrlGenerator {
public function test() {
return $this->to('/test');
}
}
Created service provider app/Acme/lib/CustomUrlServiceProvider.php
<?php namespace App\Acme\lib;
use \Illuminate\Routing\RoutingServiceProvider;
class CustomUrlServiceProvider extends RoutingServiceProvider {
public function boot() {
App::bind('url', function() {
return new CustomUrlGenerator(
App::make('router')->getRoutes(),
App::make('request')
);
});
parent::boot();
}
}
Registered service provider in app/config/app.php
Run composer dump-autoload
Now when i run {!! URL::test() !!}, im getting 404 for every route
Sorry, the page you are looking for could not be found.
NotFoundHttpException in /vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php line 143:
Is there something that i'm missing?
Many thanks for any help ..
You talk about a mistake in the RouteCollection.php file, but you don't include it in your question. Furthermore, I would have written differently in the composer.json, like this:
"autoload": {
"classmap": [
// ....
"App\\Your_Namespace\\" : "app/Acme/lib",
]
}
Related
I have created a Laravel package using the guidelines of https://laravelpackage.com/.
My package name is Company/FirstPackage.
It resides in the WebSite/packages folder of a host Laravel application.
In it I have created a controller in src/Http/Controllers:
namespace Company\FirstPackage\Controllers;
class FirstController extends Illuminate\Routing\Controller {
public function getName() {
return response()->json('hi, this is name');
}
}
And I have created a simple api.php file in the WebSite/packages/Company/FirstPackage/route directory and in it, I have this route:
use Illuminate\Support\Facades\Route;
Route::get('/name', [Company\FirstPackage\Controllers\FirstController:class, 'getName']);
Route::get('/testRoute', function() { return 'route is working'; });
The 127.0.0.1:8000/testRoute works as expected. But when I go to 127.0.0.0:8000/name I get this error:
Illuminate\Contracts\Container\BindingResolutionException Target class
[Company\FirstPackage\Controllers\FirstController] does not exist.
I have tried all suggestions in this link:
Add the namespace back manually so you can use it as you did in
Laravel 7.x and before
Use the full namespace in your route files when using the
string-syntax
Use the action syntax (recommended)
But non of them worked.
How should I fix this bug?
Update: Part of the content of the composer.json is as follow:
"autoload": {
"psr-4": {
"Company\\FirstPackage\\": "src/"
}
},
"extra": {
"laravel": {
"providers": [
"Company\\FirstPackage\\FirstPackageServiceProvider"
]
}
}
I am new in laravel.
I am writing following code in the controller method.
include_once(app_path() .'/Classes/Pgp_2fa.php');
$pgp = new Pgp_2fa();
Following errors are shown.
FatalThrowableError in AuthController.php line 146: Class
'App\Http\Controllers\Pgp_2fa' not found
You have to use the correct namespace for your class.
If you are not using any namespace, you should add a \ in front of the class to let php know that the class exists in the root namespace. Otherwise php will look in the current namespace which is App\Http\Controllers when you are in a controller.
$pgp = new \Pgp_2fa();
This is not just Laravel behavior but php in general.
When you add new classes there are couple way to use them. (I mean, load them)
If your classes has unique name and don't use namespace, then you can add backslash \ start of the class.
$class = new \Pgp_2fa;
But if you want to define them namespaces and use with same name so
many times, then you have to add these classes in composer.json. Open your
composer.json and come into "autoload" section and define class
directory in classmap
"autoload": {
"classmap": [
"database/seeds",
"database/factories",
"app/Classes", // so all classes in this directory are going to load
],
And don't forget to say composer dump-autoload after these changes and creating new classes
If you don't want to dump your composer when you add a new class,
then you may want add those classes inside of the psr-4 section in composer
"autoload": {
"psr-4": {
"App\\": "app/",
"App\\Classes\\": "app/Classes",
}
},
you need to add namespace for your custom class
or just add slash on your class name. like :
$pgp = new \Pgp_2fa();
You can call inside the constructor like below, and you can use the
$Pgp_2fa variable in remaining function
class controllername extends Controller
{
public function __construct(Route $route,Request $request)
{
$Pgp_2fa = new \Pgp_2fa();
}
}
You can easily add your custom classes by added it to Composer's autoload array. Go to composer.json and add it to:
"autoload": {
"files": [
"app\\Classes\\Pgp_2fa.php"
]
},
Now in your app folder, under classes folder add your Pgp_2fa.php file which will have your class. You can use it anywhere you want, it should be automatically auto-load-ed.
After adding your class write command:
composer dumpautoload to refresh autoload class mapping.
For example, There is our class Common.php in a directory called Mylibs in app directory.
app/mylibs/Common.php
we need to namespace App\Mylibs;
namespace App\Mylibs;
class Common {
public function getSite() {
return 'AmirHome.com';
}
}
Now, you can access this class using the namespace within your classes just like other Laravel classes.
use App\Mylibs\Common
in Controller:
namespace App\Http\Controllers;
use App\Mylibs\Common;
class TestController extends Controller {
protected $common;
public function __construct(Common $common) {
$this->common = $common;
}
public function index() {
echo $this->common->getSite();
}
}
I'm new on laravel and need some help.
Actualy i use 5.3 laravel version.
I need to use, in laravel, external company framework (call it F for semplicity).
This framework is some like process manager. Actualy, for integrate it with laravel i put it in laravel/public folder, this way i can use laravel and F's pages in same domain. In laravel i need to access to some F functionality wich is all collect in class FFramework\Facade\FInterface;
Then i want to acces to this class from laravel controller FController.
But when i run code i get Class Not Found Exception.
This is folder structure:
laravel
app
http
controllers
FController.php
public
css
js
index.php
fframework
facade
FInterface.php
index.php
This is code example:
FController.php
<?php
namespace App\Http\Controllers;
use FFramework\facade\FInterface;
class FController extends Controller {
public function getSimpleDAta() {
$f = new FInterface();
return $f->getSimpleData();
}
}
FInterface.php
<?php
namespace FFramework\facade;
use some\internal\function;
class FInterface {
public function getSimpleDAta() {
$simpleData = ...omg so much computation :) ...
return $simpleData;
}
}
Exception that i get:
Class 'FFramework\facade\FInterface' not found
Additional Information
I use standard LAMP configuration
PHP version is last 5.6 stable version
Question
How can i use FInterface from Laravel controller leaving FFramework in public folder?
You need to update the autoload section of your composer.json file to tell your project where to look for files in the FFramework namespace.
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/"
"FFramework\\": "public/fframework"
}
},
This question already has answers here:
How to create custom helper functions in Laravel
(23 answers)
Closed 7 months ago.
If I wanted to make a currentUser() function for some oauth stuff I am doing where I can use it in a view or in a controller (think rails, where you do helper_method: current_user in the application controller).
Everything I read states to create a helpers folder and add the function there and then that way you can do Helpers::functionName Is this the right way to do this?
Whats the "laravel way" of creating helper functions that can be used in blade templates and controllers?
Create a new file in your app/Helpers directory name it AnythingHelper.php
An example of my helper is :
<?php
function getDomesticCities()
{
$result = \App\Package::where('type', '=', 'domestic')
->groupBy('from_city')
->get(['from_city']);
return $result;
}
generate a service provider for your helper by following command
php artisan make:provider HelperServiceProvider
in the register function of your newly generated HelperServiceProvider.php add following code
require_once app_path('Helpers/AnythingHelper.php');
now in your config/app.php load this service provider and you are done
'App\Providers\HelperServiceProvider',
An easy and efficient way of creating a global functions file is to autoload it directly from Composer. The autoload section of composer accepts a files array that is automatically loaded.
Create a functions.php file wherever you like. In this example, we are going to create in inside app/Helpers.
Add your functions, but do not add a class or namespace.
<?php
function global_function_example($str)
{
return 'A Global Function with '. $str;
}
In composer.json inside the autoload section add the following line:
"files": ["app/Helpers/functions.php"]
Example for Laravel 5:
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/"
},
"files": ["app/Helpers/functions.php"] // <-- Add this line
},
Run composer dump-autoload
Done! You may now access global_function_example('hello world') form any part of your application including Blade views.
Laravel global helpers
Often you will find your self in need of a utility function that is access globally throughout you entire application. Borrowing from how laravel writes their default helpers you're able to extend the ability with your custom functions.
Create the helper file, not class
I prefer to you a file and not a class since I dont want to bother with namespaces and I want its functions to be accessible without the class prefixes like: greeting('Brian'); instead of Helper::greeting('Brian'); just like Laravel does with their helpers.
File: app/Support/helper.php
Register helper file with Composer: composer.json
{
...
"autoload": {
"classmap": [
"database"
],
"files": [
"app/Support/helpers.php"
],
"psr-4": {
"App\\": "app/"
}
},
...
}
Create your first helper function
<?php
if (!function_exists('greet')) {
/**
* Greeting a person
*
* #param string $person Name
* #return string
*/
function greet($person)
{
return 'Hello ' . $person;
}
}
Usage:
Remember to autoload the file before trying to access its functions:
composer dump-autoload
Let's test with Tinker
$ php artisan tinker
Psy Shell v0.8.17 (PHP 7.0.6 ΓÇö cli) by Justin Hileman
>>> greet('Brian');
=> "Hello Brian"
>>> exit
Exit: Goodbye.
With Blade
<p>{{ greet('Brian') }}</p>
Advanced usage as Blade directive:
A times you will find yourself wanting to use a blade directive instead of a plain function.
Register you Blade directive in the boot method of AppServiceProvider: app/Providers/AppServiceProvider.php
public function boot()
{
// ...
Blade::directive('greet', function ($expression) {
return "<?php echo greet({$expression}); ?>";
});
}
Usage:
<p>#greet('Brian')</p>
Note: you might need to clear cache views
php artisan view:clear
The above answers are great with a slight complication, therefore this answer exists.
utils.php
if (!function_exists('printHello')) {
function printHello()
{
return "Hello world!";
}
}
in app/Providers/AppServiceProvider.php add the following in register method
public function register()
{
require_once __DIR__ . "/path/to/utils.php"
}
now printHello function is accessible anywhere in code-base just as any other laravel global functions.
Another option, if you don't want to register all your helper functions one by one and wondering how to register them each time you create a new helper function:
Again in the app/Providers/AppServiceProvider.php add the following in register method
public function register()
{
foreach (glob(app_path().'/Helpers/*.php') as $filename) {
require_once($filename);
}
}
I am starting out with Laravel 5 and as first order of business I want to move all my models into a folder called Models.
But how can I access those without specifying the namespace like in the following?:
...
class UserRolesTableSeeder extends Seeder {
public function run()
{
DB::table('user_roles')->delete();
App\Models\UserRoles::create(['name' => 'CREATE_USER']);
}
}
Go into your composer.json and add at the end of "autoload": "classmap" this line "app/models". This way you are telling laravel to autoload those clases. After that, run a composer update and it should work.
You can also create a service provider to access models without namespaces.
To create a service provider, here is what you have to do :
1) Create a file in your models directory and name it ModelsServiceProvider.php
2) Inside of it write this code
<?php
namespace App\Models;
use Illuminate\Support\ServiceProvider;
class ModelsServiceProvider extends ServiceProvider {
public function register()
{
$this->app->booting(function()
{
$loader = \Illuminate\Foundation\AliasLoader::getInstance();
$loader->alias('UserRoles', 'App\Models\UserRoles');
});
}
3) Go into app/config/app.php and under providers array add this line 'App\Models\ModelsServiceProvider'
You can also add directly your aliases for classes under the aliases array inside app/config/app.php.
Alternatively, you can just load your models into the global namespace like you were doing before! It's a bit scary to go against the docs but so far we haven't had any issues with it.
To make sure your models are still loaded, you just need to add the reference to your composer.json:
(assumes your namespace is App\Models)
"autoload": {
"classmap": [
...
"app/Models/"
],
...
"": [
"app/Models/"
]
be sure to run composer dump-autoload