i have some custom function and i'm trying to use that into project, for example:
function makeText($str1, $str2){
return $str1 . ' '. $str2;
}
and i want to use this function in view such as :
<div style='float:left;'>MakeText : {{makeText("Hello","World");}}</div>
makeText is only sample function, witch folder must be put functions method such as UF.php containes all functions and how to define this file to laravel and use it?
You could follow Laravel’s conventions and create a helpers.php file in your app directory. Be sure to auto-load it with Composer though:
"autoload": {
"classmap": [
//
],
"files": [
"app/helpers.php"
]
},
You can then use the function any where in your application, including views.
Laravel gives you a few options. You can include your function definition inside of any of the files that get automatically included and achieve the result you want, such as /app/start/global.php, /bootstrap/start.php, /app/routes.php or many others. The problem with this approach is that, depending on the name of your function, there is a non-negligible likelihood that the name might conflict with one that is already taken (or may get taken later). Also, if you ever need to debug this function you will need to be able to find it later.
You can get around this issue by placing your function inside of a class, and then call that class a service. You can then inject that class into your controller via dependency injection and then pass that data to your view:
class MyService
{
public function makeText($param1, $param2)
{
return $param1 . ' ' . $param2;
}
}
class AController extends BaseController
{
public function __construct(MyService $serv)
{
$this->serv = $serv;
}
public function aRoute()
{
return View::make('some.view')
->with('serv', $this->serv);
}
}
And then in your view:
<div style='float:left;'>MakeText : {{ $serv->makeText("Hello","World"); }}</div>
This will help you prevent naming collisions because you can easily place MyService into any namespace that makes sense. It will also help you keep your code organized better.
Something this simple will probably not require a service provider, but as you add complexity to your project it would be an easy step to do once you need to.
Related
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.
I'm trying to improve my code OOP wise.
I have the tendancy to put some of my bussiness logic inside my Controller.
Some people told me this is not desirable.
I know that when you are working with Posts for example. You can simply put your bussiness logic in your Post.php Model.
I now have a feature where i upload an .xlsx file and it has to be checked and validated if the format of the .xlsx is correct.
It is currently inside ScheduleController#storeDeliveryXlsx.
But i don't have a specified model for this to store the validation inside?
Is this where Repositories design pattern is needed? Or is it fine to create a model that doesn't communicate with the database like: DeliveryFile.php where i put the logic that i later can use throughout my app like this: DeliveryFile::validate($file); or DeliveryFile::upload(file);.
I think i'm likely to re-use the same validation on the .xlsx for multiple instances. So i'd like to do something like Model::validate($file);. But i don't know where to put the code.
In this case, I would personally recommend using a Service. A service class is essentially for common functionality that you may repeat across multiple controllers. The Service Layer is a design pattern that will help you to abstract your shared logic to a common service i.e. our new Service Class.
So in your instance, you could have a Service class such as ExcelValidator and then use something like the following to structure your approach.
<?php
namespace App/Services;
class ExcelValidatorService
{
public function validate($file)
{
// our validate logic
}
}
And then in your controllers or models, you can call the ExcelValidator service to implement your repeated validate logic.
The phrase I now have a feature would keep on repeating itself in the course of the lifetime of the code you are writing. Having separate controller, service, model classes, OOP design, modular code would definitely help in that regard. Now it might be easier, but it will keep on becoming difficult with time
Recently I faced a similar problem, in my case I need to use, as model, a Restful API.
In composer.json I added under autoload
"psr-4": {
"App\\": "app/",
"MYCOMP\\": "app/MYCOMP/"
},
Under app folders I added MYCOMP folder with two subfolders Providers and Restmodels.
In config/app.php in providers array I added only:
MYCOMP\Providers\RestModelServiceProvider::class,
In app/MYCOMP/Providers/RestModelServiceProvider.php I register all providers and facades for my rest models:
public function register()
{
$loader = \Illuminate\Foundation\AliasLoader::getInstance();
$models = glob( realpath(__DIR__."/../") ."/RestModels/*/*RestModel.php");
foreach($models as $model){
$bnmodel = basename($model);
if($bnmodel !== "BaseRestModel.php" && $bnmodel !== "BaseFacadeRestModel.php"){
list($n, $niente) = explode("RestModel.php", $bnmodel);
list($bnnoext, $niente) = explode(".php", $bnmodel);
$res = $n.'Repository';
$fold = basename(dirname($model));
$nc = "\\MYCOMP\\RestModels\\".$fold."\\".$bnnoext;
$this->app->bind($res, function($app) use ($nc) {
return new $nc;
});
$loader->alias($res, $nc."Facade");
}
}
}
This code is specific for my project and for how I structured folders.
For all rest models I have two files:
app/MYCOMP/RestModels/{ModelName}/{ModelName}RestModel.php
app/MYCOMP/RestModels/{ModelName}/{ModelName}RestModelFacade.php
The only exceptions are: BaseRestModel and BaseFacadeRestModel these classes are extended by all RestModel and RestModelFacade. So I'd implement something like validate under BaseRestModel.
BaseFacadeRestModel just contains:
<?php
namespace MYCOMP\RestModels\Base;
use Illuminate\Support\Facades\Facade;
class BaseFacadeRestModel extends Facade{
private $facadeName;
protected static function getFacadeName(){
list($senzasuffisso, $niente) = explode("RestModelFacade", static::class);
$nc = last(explode("\\", $senzasuffisso));
return $nc;
}
protected static function getFacadeAccessor() {
return static::getFacadeName().'Repository';
}
}
So all the other Facades work just exteding BaseFacadeRestModel.
In laravel 4 i just used a function
$varbl = App::make("ControllerName")->FunctionName($params);
to call a controller function from a my balde template(view page).
Now i'm using Laravel 5 to do a new project and i tried this method to call a controller function from my blade template .But its not working and showing some errors.
Is there any method to call a controller function from a view page in Laravel 5?
Just try this in your view :
{{ ControllerName::Functionname($params); }}
OR
<?php echo ControllerName::Functionname($params);?>
Refer this : http://laravel.io/forum/03-06-2014-what-is-the-proper-way-to-call-controllers-from-the-view?page=1
If you have a function which is being used at multiple places you should define it in helpers file, to do so create one (may be) in app/Http/Helpers folder and name it helpers.php, mention this file in the autoload block of your composer.json in following way :
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/"
},
"files": [
"app/Http/Helpers/helpers.php"
]
},
run composer dump-autoload, and then you may call this function from anywhere, let it be controller view or model.
or if you don't need to put in the helpers. You can just simply call it from it's controller. Just make it a static function.
Create.
public static function funtion_name($args) {}
Call.
\App\Http\Controllers\ControllerName::function_name($args)
If you don't like the very long code, you can just make it
ControllerName::function_name($args)
but don't forget to call it from the top of the view page.
use \App\Http\Controllers\ControllerName;
In laravel 5, you can do it like so
In your view:
<?php use App\Http\Controllers\ControllerName;
echo ControllerName::functionName(); ?>
The functionName should have the 'static' keyword e.g
Controller function:
public static function functionName() {
return "Hello World!";
}
You can actually call a class, helper class or any declared class in your blade template but putting it in the aliases array of your app.php in the config folder
'Helper' => App\Http\Helpers\Helper::class,
Using the Helper as an alias, you can reference it in your blade template, example below:
{{Helper::formatDateToAgo ($notification->created_at)}}
For accessing a method of a Controller from a view page you need to give the full path of that controller in your blade page.
use App\Http\Controllers\AdminAfterAuth;
$admin_dtls = AdminAfterAuth::globAdmin();
Here AdminAfterAuth is the controller class name and globAdmin is the method name.
Now in your controller declare the method statically.
public static function globAdmin(){
$admin_val = AdminLogin::where('id',session('admin_id'))->get();
return $admin_val;
}
In view call the function like this:
#php
use App\Http\Controllers\ControllerName;
$var = ControllerName::FunctionName();
#endphp
But if the function name in the controller is as:
public function FunctionName(){
return something;
}
Then an error will be shown:
Non-static method App\Http\Controllers\ControllerName::FunctionName() should not be called statically(...)
So to solve this problem "non-static" you have to change your function like this:
public static function FunctionName(){
return something;
}
Then you are all done.
I like and favor Khan Shahrukh way, it is better to create a helpers files with all your functions, then add it to your composer.json file:
"autoload": {
"files": [
"app/Http/Helpers/helpers.php"
]
},
You can select the path that suits you, then dump-autoload composer to make it includes the new file.
For usability and clean work, after that you will be able to invoke your function on any view file OR project parts : Controller, Model.
If you decided to go with the public static method Don't forget to add this line at the very top of your view:
use \App\Http\Controllers\ControllerName;
In my blade view (Laravel), I used below blade syntax (specify full path) to call my controller action.
{{ App\Http\Controllers\mynestedpageController::index() }}
Controllers methods are not supposed to be called from the view. Best options are to call the method from the method which is returning the view object, which contains the output which you then can echo in the view;
public function bar() {
$foo = $this->foo();
return view( 'my.view', compact( 'foo' ) );
}
protected method foo()
{
return 'foobar';
}
second option to add a helpers file to the compose.json file
"autoload": {
"files": [
"app/helpers.php"
]
},
dump your autoload and you can call these functions from anywhere inside your application
Actually below should work as per Laravel 5:
Usage: App::make(ControllerName)->functionName($parameters);
Example: App:make("TestController")->getUserInfo('user_id' => 9);
Please post the actual error you are getting!
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);
}
}
Im new to Laravel and namespaces, but a colleague told me i have to use the namespaces and place all my models in a folder in the app directory, named after the project.
As far as i know this means that in every single controller that uses one or more models, have have to set "use" for every model my controller needs. Example:
<?php
use Foo\Entities\Entity;
use Foo\Entities\Inheritance;
use Foo\Entities\Type;
class EntitiesController extends BaseController {
public function index()
{
$inheritances = Inheritance::all();
$entities = Entity::all();
return View::make('settings/entities')
->with('entities', $entities)
->with('inheritances', $inheritances);
}
}
If we asume that the associated models above will be used everywhere, would it be completely crazy to put the models in the /app/model/ folder and if a controller need a model which overwrite the standard system, then use namespaces?
First things first: namespaces are NOT a Laravel thing, but a PHP feature created to better organize our code.
So, if you want your code organized, you should use namespaces for everything and, yes, you'll have to add 'use' clauses in the top of most of your PHP files. But in Laravel you also can be free to not use namespaces at all, you just have to add your autoload classes directories to your composer.json file:
"autoload": {
"classmap": [
"models"
],
},
Execute
composer dumpautoload
So Composer read all files in your models folder, to create a class map of them, and then you can just drop all uses clauses:
class EntitiesController extends BaseController {
public function index()
{
$inheritances = Inheritance::all();
$entities = Entity::all();
return View::make('settings/entities')
->with('entities', $entities)
->with('inheritances', $inheritances);
}
}
To not use namespaces in your PHP application, these days, may be considered a code smell. The only 'part' of Laravel where people doesn't usually use namespaces is Controllers, but this is also changing in Laravel 5, where controllers will be namespaced by default, but still, you will have the option to not use them, because this is a Composer/PHP thing, not Laravel.
Taylor Otwell has 3 big things always in mind when creating features and evolving Laravel: Best practices, fast coding and beautiful code.
EDIT
Answering your comment, if all your controllers needs to have access to some service or even model, why not add it to your BaseController?
But you may have to take a read at the repository pattern, because your controllers should not really be aware of your models. Developers are now creating a new layer (repository) between controllers and models, and perform the operations in those layers. You can, also, make use of Laravel Dependency Injection to help you with those use clauses you don't like.
It would be something like this:
Create a repository interface:
interface EntityRepositoryInterface {
}
Create the repository:
use Foo\Entities\Entity;
class EntityRepository {
public function find($id)
{
return Entity::find($id);
}
public function all()
{
return Entity::all();
}
}
Create your controllers using your repository:
class EntitiesController extends BaseController {
public function __construct(EntityRepositoryInterface $entityRepository)
{
$this->entityRepository = $entityRepository;
}
public function index()
{
$entities = $this->entityRepository->all();
return View::make('settings/entities')
->with('entities', $entities);
}
}
And you have to tell Laravel Dependency Injection what to instantiate when it needs a EntityRepositoryInterface:
App::bind('EntityRepositoryInterface', 'Foo\Entities\EntityRepository');
There's nothing wrong with putting your models anywhere you like. In fact, I put all my models that extend directly from Eloquent in app/models. You are free to follow this, or not follow it, in your own project.
However, this does come with a caveat. Very few of my classes actually directly interact with these models (Repositories are pretty much it). Those I do put in separate namespaces which are then injected into my controllers. Consequently, I must either use each repository that a controller needs at the top of each file or specify the fully qualified class name every time I reference it.