How do I make global helper functions in laravel 5? [duplicate] - php

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);
}
}

Related

PHP Laravel 5.2 - Call function in another file [duplicate]

I have two controller file homecontroller and backendcontroller. What is the best way to create global function and access it from both files?
I found here Arian Acosta's answer helpful but I wonder if there is an easiest way. I would appreciate any suggestions.
Solution
One way to do this is to create a class and use its instance, this way you can not only access the object of the class within a controller, blade, or any other class as well.
AppHelper file
In you app folder create a folder named Helpers and within it create a file name AppHelper or any of your choice
<?php
namespace App\Helpers;
class AppHelper
{
public function bladeHelper($someValue)
{
return "increment $someValue";
}
public function startQueryLog()
{
\DB::enableQueryLog();
}
public function showQueries()
{
dd(\DB::getQueryLog());
}
public static function instance()
{
return new AppHelper();
}
}
Usage
In a controller
When in a controller you can call the various functions
public function index()
{
//some code
//need to debug query
\App\Helpers\AppHelper::instance()->startQueryLog();
//some code that executes queries
\App\Helpers\AppHelper::instance()->showQueries();
}
In a blade file
Say you were in a blade file, here is how you can call the app blade helper function
some html code
{{ \App\Helpers\AppHelper::instance()->bladeHelper($value) }}
and then some html code
Reduce the overhead of namespace (Optional)
You can also reduce the overhead of call the complete function namespace \App\Helpers by creating alias for the AppHelper class in config\app.php
'aliases' => [
....
'AppHelper' => App\Helpers\AppHelper::class
]
and in your controller or your blade file, you can directly call
\AppHelper::instance()->functioName();
Easy Solution:
Create a new Helpers folder in your app directory.
Create a php file named your_helper_function.php in that Helpers directory.
Add your function(s) inside your_helper_function.php
function your_function($parameters){
//function logic
}
function your_another_function($parameters){
//function logic
}
Add this file to the Files key of your composer.json like
"autoload": {
...
"files": [
"app/Helpers/your_helper_function.php"
]
...
}
Finally, regenerate composer autoload files. (Run this in your project directory)
composer dump-autoload
That's it! and now you can access your_function() or your_another_function() in any part of your Laravel project.
If you still have any confusion, check my blog post on how to do this:
How to Add a Global Function in Laravel Using Composer?
Updated:
Step 1
Add folder inside app folder
app->Helper
Step 2
add php Class inside Helper folder
Eg. Helper.php
Add namespace and class to the Helper.php
namespace App\Helper;
class Helper
{
}
Register this Helper.php into config/app.php file
'aliases' => [
....
'Helper' => App\Helper\Helper::class
]
Now, write all the functions inside Helper.php and it will be accessible everywhere.
How to access from Controller?
Step 1 - Add a namespace at top of the controller.
use App\Helper\Helper;
Step 2 - Call function - Assume there a getInformation() inside the Helper Class.
$information = Helper::getInformation()
In your Controller.php which extends BaseController, you can create a function like;
public function data($arr = false)
{
$data['foo'] = 'bar';
return array_merge($data,$arr);
}
And from any controller when you send a data to a view;
public function example()
{
$data['smthg'] = 'smthgelse';
return view('myView',$this->data($data));
}
The data in the the main controller can be accessed from all controllers and blades.
The Laravel Service Provider way
I've been using global function within Laravel for a while and I want to share how I do it. It's kind of a mix between 2 answers in this post : https://stackoverflow.com/a/44021966/5543999 and https://stackoverflow.com/a/44024328/5543999
This way will load a file within a ServiceProvider and register it within your Laravel app.
Where is the difference, the scope, it's always about the scope.
Composer //Autload whitin composer.json method
|
|--->Laravel App //My method
|
|--->Controller //Trait method
|--->Blade //Trait method
|--->Listener //Trait method
|--->...
This is a really simplist way to explain my point, all three methods will achieve the purpose of the "Global function". The Traits method will need you to declare use App\Helpers\Trait; or App\Helpers\Trait::function().
The composer and service provider are almost about the same. For me, they answer better to the question of what is a global function, because they don't require to declare them on each place you want to use them. You just use them function(). The main difference is how you prefer things.
How to
Create the functions file : App\Functions\GlobalFunctions.php
//App\Functions\GlobalFunctions.php
<?php
function first_function()
{
//function logic
}
function second_function()
{
//function logic
}
Create a ServiceProvider:
//Into the console
php artisan make:provider GlobalFunctionsServiceProvider
Open the new file App\Providers\GlobalFunctionsServiceProvider.php and edit the register method
//App\Providers\GlobalFunctionsServiceProvider.php
public function register()
{
require_once base_path().'/app/Functions/GlobalFunctions.php';
}
Register your provider into App\Config\App.php wihtin the providers
//App\Config\App.php
'providers' => [
/*
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
...
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
App\Providers\GlobalFunctionsServiceProvider::class, //Add your service provider
Run some artisan's commands
//Into the console
php artisan clear-compiled
php artisan config:cache
Use your new global functions
//Use your function anywhere within your Laravel app
first_function();
second_function();
Laravel uses namespaces by default. So you need to follow the method described in that answer to setup a helper file.
Though in your case you want to access a method in different controllers. For this there's a simpler way. Add a method to you base controller app/Http/Controllers/Controller.php and you can access them in every other controller since they extend it.
// in app/Http/Controllers/Controller.php
protected function dummy()
{
return 'dummy';
}
// in homecontroller
$this->dummy();
There are a few ways, depending on the exact functionality you're trying to add.
1) Create a function inside Controller.php, and make all other controller extend that controller. You could somewhat compair this to the master.blade.php
2) Create a trait, a trait can do a lot for you, and keeping ur controllers clean. I personally love to use traits as it will look clean, keep my Controller.php from being a mess with tons of different lines of code.
Creating a global function
create a Helpers.php file under a folder, let's name it 'core'.
core
|
-- Helpers.php
namespace Helpers; // define Helper scope
if(!function_exists('html')) {
function html($string) {
// run some code
return $str;
}
}
In your composer.json
"autoload": {
"psr-4": {
},
"files": [
"core/Helpers.php"
]
}
in the file that you want to use it
// the " use " statement is not needed, core/Helpers is loaded on every page
if(condition_is_true) {
echo Helpers\html($string);die();
}
Remove the namespace in Helpers.php if you want to call your function without the need to prefix namespace. However I advise to leave it there.
Credit: https://dev.to/kingsconsult/how-to-create-laravel-8-helpers-function-global-function-d8n
By using composer.json and put the function containing file(globalhelper.php) to the autoload > files section, then run
composer dump-autoload
You can access the function inside the file(globalhelper.php) without having to calling the class name, just like using default php function.

Custom helper classes in Laravel 5.4 [duplicate]

This question already has answers here:
How to create custom helper functions in Laravel
(23 answers)
Closed 7 months ago.
I have some helper classes in app/Helpers. How do I load these classes using a service provider to use them in blade templates?
e.g. If I have a class CustomHelper that contains a method fooBar() :
<?php
nampespace App\Helpers;
class CustomHelper
{
static function fooBar()
{
return 'it works!';
}
}
I want to be able to do something like this in my blade templates:
{{ fooBar() }}
instead of doing this:
{{ \App\Helpers\CustomHelper::fooBar() }}
P.S: #andrew-brown's answer in Best practices for custom helpers on Laravel 5 deals with non-class files. It would be nice to have a class based solution so that the helper functions can be organized among classes.
I don't think it's possible to use only function when you have code in your classes. Well, you could try with extending Blade but it's too much.
What you should do is creating one extra file, for example app\Helpers\helpers.php and in your composer.json file put:
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/"
},
"files": ["app/Helpers/helpers.php"] // <- this line was added
},
create app/Helpers/helpers.php file and run
composer dump-autoload
Now in your app/Helpers/helpers.php file you could add those custom functions for example like this:
if (! function_exists('fooBar')) {
function fooBar()
{
return \App\Helpers\CustomHelper::fooBar();
}
}
so you define global functions but in fact all of them might use specific public methods from some classes.
By the way this is exactly what Laravel does for its own helpers for example:
if (! function_exists('array_add')) {
function array_add($array, $key, $value)
{
return Arr::add($array, $key, $value);
}
}
as you see array_add is only shorter (or maybe less verbose) way of writing Arr::add

Laravel use external class

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"
}
},

Laravel 5 Extending core class

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",
]
}

Include a file in laravel controller?

I am creating a project with some additional functionality provided in form of a .php file API which contains some functions and some classes(out of which some class names are conflicting with Laravel built in class names) so, my question how should I include this file in my Laravel Controller to call functions in the file which using the classes of the file without referring Laravel classes and with less or no modification in .php API file?
Note* I am using Laravel-5.1
If you have a custom file containing some classes/functions that need to be loaded for every request, you need to make sure it's added to the autoloader.
In your composer.json add the following in your autoload section:
"autoload": {
"files": [
"path/to/your/File.php"
]
}
This will make sure the file is loaded. Now what you need is a way to use those classes without conflicting with existing Laravel classes.
First, make sure you have a namespace declaration at the top of your included file - say namespace Your\Namespace. In order to avoid conflicts, you need to explicitly tell PHP which class you mean when you reference it in the code. You mentioned your file contains a Response class that also exists in Laravel. In order to be able to use both, you need to alias one of them:
use Illuminate\Http\Response as LaravelResponse;
use Your\Namespace\Response;
Now in your code you can refer to Laravel's Response class as LaravelResponse, and to your response by simply Response.
Location of the file is irrelevant, as long as it's in a folder accessible to Laravel and its patch is added to composer.json.
Keep in mind that storing multiple classes per file is discouraged as a bad practice. I strongly suggest that you split your fine into separate file per class + one additional file with global functions.
Make an alias
Ex.
use App\Http\Requests\Request as DifferentRequest;
DifferentRequest->doStuff();
Aliasing/Importing
make an alias as #user2504370 proposed,
add to the composer:
"autoload": {
"classmap": [
"database",
"place_with_your_file",
],
"psr-4": {
"App\\": "app/",
"your_namespace": "your path",
}
},
and run
composer dump-autoload
EDIT:
there was a typo in classmap. I wanted to tell you you can put your file whenever you want, for example, you can create a new folder 'place_with_your_file', which is not necessarily inside Laravel's folder.
I'm using it with my external libraries.
For PSR-4: if you are using namespaces, then here you will register the base namespace and the folder where can be found:
for example: "Utilities\\": "../utilities/app"
or whichever your path is.
and for classmap, you need to include path to this folder:
"../utilities/app"
and your autoload will look something like this:
"autoload": {
"classmap": [
"database",
"../utilities/app",
],
"psr-4": {
"App\\": "app/",
"Utilities\\": "../utilities/app"`
}
},
Thank you all for taking efforts in trying to solve my problem but none of the solution worked for me so, here is what I tried for my problem
Below is the structure of my php file that I wanted to includes/integrate
<?php
class Misc {
const SUCCESS = 1;
const FAILURE = 0;
public static function get_hash ( $key )
{
...
...
...
}
public static function show_reponse ( $result )
{
...
}
}
function check($keyhash)
{
...
...
...
}
function function2()
{
...
...
...
}
class Response {
public function __construct ( $key )
{
...
}
public function __destruct ()
{
unset( $this->key );
unset( $this->params );
}
public function __set ( $key)
{
...
}
public function __get ( $key )
{
return $this->params[$key];
}
private function check_now ()
{
...
}
}
The main problem I was facing is the class name Response which was conflicting with Laravel Response class so I just removed all classes from the file and moved to their individual files in a new folder in Laravel\App folder and added namespaces to all classes.
Then I moved all functions in a PHP file in laravel\App directory
and used classnames along with the namespace defined and since I moved all functions in a different PHP file I could easily call the functions
so here is my final folder structure of Laravel
Laravel
-App
-Console
-Events
-Exceptions
-...
-Libraries(Folder Containing Individual PHP files of classes from original file)
-Providers
-helpers.php(File containing all functions from original file)
-User.php
-bootstrap
-...
-...

Categories