So I'm writing a Laravel 4 app and I've setup namespaces. I'm just trying to write some systemwide functionality that I can execute from anywhere mainly to create menus/setup language/currencies etc.
I have directory to global called "library" which has currently a file called Menu.php inside it which looks as follows:
<?php
namespace Library;
use AppName\Model\Menu as MenuModel;
class Menu {
public static function BuildMenu($id = 1) {
//retrieve menu
$menu = MenuModel::GetMenu($id);
//sort content for page
$data = $menu->toArray();
print_r($data);
}
}
I am currently attempting to call the BuildMenu function in the filters.php file with the following:
App::before(function($request)
{
//
View::share('Menu', Library\Menu::BuildMenu());
});
I get a class 'Library\Menu' not found error from laravel. I'm presuming this is something to do with my lack of knowledge of namespaces so any clarity would be appreciated.
Did you add your library path to composer.json ?
if not, just add it to autoload > classmap >> app/library
and run artisan dump-autoload
should be fine.
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 working on a project and it's getting a little too hard for me...
I explain.
I need to parse PDF files with PHP, to analyse the content of those files. To do that, I use pdfparser.org library.
I firstly tried to include this library as usually, without any result.
After having read all the Internet, since this library requires Composer to be installed (and on my web hosting I can't get Composer installed), I have applied the Composer process on my Windows PC. I got the "vendor" folder with the "autoload.php" file. Fine !!
Then, I have tried to include it properly in CodeIgniter. The solution I chose is :
Creating a file "Pdfparser.php" in application/libraries/
class Pdfparser
{
public function __construct()
{
require_once APPPATH."/third_party/pdfparser.php";
}
}
Then, I add the PdfParser "Composer" application in application/third_party/, and in the /third_party/pdfparser.php I simply put :
if (!defined('pdfparser')) {
define('pdfparser', dirname(__FILE__) . '/');
require(pdfparser . 'pdfparser/autoload.php');
}
Then, I add this library to CodeIgniter /application/config/autoload.php as :
$autoload['libraries'] = array('pagination', 'form_validation','email','upload','pdfparser');
Finally, I call it in my function in application/controllers/Admin.php :
$parser = new Pdfparser();
$pdf = $parser->parseFile(myfile.pdf);
$full_text = $pdf->getText();
(This 4. block of code is directly taken from official Documentation here : http://www.pdfparser.org/documentation, and just adapted).
But now, I break the Internet... I have this error :
PHP Fatal error: Call to undefined method PdfParser::parseFile() in /path/application/controllers/Admin.php on line 3083
After having looked CodeIgniter documentation, I try to add the Composer autoloader to the core... in application/config/autoload.php I put :
$config['composer_autoload'] = APPPATH . "/third_party/pdfparser/autoload.php";
Of course, it doest not work. And I'm lost...
Use composer properly. $config['composer_autoload'] = TRUE; and inside your application folder run composer install smalot/pdfparser . Then inside your controller it should run, if not use Use :)
use Smalot\PdfParser;
class My_controller extends CI_Controller {
}
When using composer, to include a library in your project you do something like that :
composer install smalot/pdfparser
Then, to include the newly installed library, you only need to include the "autoload.php" file provided by composer :
<?php
include 'vendor/autoload.php';
$parser = new Pdfparser();
$pdf = $parser->parseFile(myfile.pdf);
$full_text = $pdf->getText();
var_dump($full_text);
Nothing more.
Replace your code
class Pdfparser
{
public function __construct()
{
require_once APPPATH."/third_party/pdfparser.php";
}
}
with
<?php
require_once APPPATH."/third_party/pdfparser.php";
class Pdfparser
{
public function __construct()
{
}
}
Include outside of your class.
Rather than using autoloading you can load library like this...
$this->load->library('library_name');
Example:
$this->load->library('pdfparser');
I've created a helper file using the following method:
Created file in app/Http/helpers.php
Added file path in composer.json
Run this command: composer dumpautoload
Everything worked well but I want to use my models here so that I don't have to write code for getting data from database every time, but it's giving an error that model class not found.
function productImagePath($image_name) {
$generalSettings = \GeneralSettingsModel::GetGeneralSettings();
return $generalSettings;
}
My requirement is that I want to call some model's functions to get frontend (header/footer) design settings from database. So I've to write that code again and again in each controller. I'm very new in Laravel so if it's not a good approach to use helpers for such things, please guide me how it's possible then.
As your GeneralSettingModel class is in the App namespace you will need to include that:
function productImagePath($image_name)
{
$generalSettings = App\GeneralSettingsModel::GetGeneralSettings();
return $generalSettings;
}
Hope this helps!
I was reading some tutorials on creating custom classes for Laravel. I followed instructions and did exactly what tutorials say:
Created new folder laravel/app/libraries/graphics/
Edited laravel/app/start/global.php where I added:
app_path().'/libraries/graphics',
Created new file in laravel/app/libraries/graphics/ named Image.php with this code:
<?php namespace graphics/Image;
class Image {
public static function hello() {
return 'Hello';
}
}
Used composer dump-autload command
Route::get('/' , function() { return Graphics\Image::hello(); } ); is returning error:
Use of undefined constant graphics - assumed 'graphics'
I also added "app/libraries/graphics/Image.php"line into composer.json autload section, which should not be neccessary. Why I am getting this error? Every tutorial shows the same procedure for this, but why it doesn't work?
Shouldn't your namespace just be graphics? The current file creates graphics\Image\Image. Try removing Image from your namespace.
<?php namespace graphics;
class Image {
public static function hello() {
return 'Hello';
}
}
Have you tried using artisan dump-autoload instead?
It will clear all of Laravel's compiled code.
See here: What are differences between "php artisan dump-autoload" and "composer dump-autoload"
You don't need to confusion for yourself. I'm resolve issue into Laravel 5. You don't need to add "app/libraries/graphics/Image.php"line into composer.json autload section because By default, app directory is namespaced under App and is autoloaded by Composer using the PSR-4 autoloading standard.
<?php
namespace App\libraries\graphics;
class Image {
public static function hello() {
return 'Hello';
}
}
and now use your Image Class from your route.
Route::get('graphics',function(){
echo \App\libraries\graphics\Image::hello();
});
The error I'm getting is that the controller doesn't exist even though I know it does, here's the code.
Route.php
Route::get('mdpay/template', array("uses" => "templateController#index"));
templateController.blade.php
class templateController extends BaseController {
public function index()
{
echo "made it";
}
}
Why might I be getting this error: Class TemplateController does not exist
================= UPDATE: ==================
Ok, so I've created the correct route, renamed my file, and corrected the class name and I'm still coming up with that error.
File Names:
templateController.php
// File Name: TemplateController.php
class TemplateController extends BaseController {
public function index()
{
// app/views/myView.blade.php
echo "hello";
}
}
My route is:
Route::get('mdpay/template', array("uses" => "TemplateController#index"));
Still receiving Controller Doesn't Exist error. All my other controllers (3 others) are working except this one.
If you are using the standard composer classmap autoloader you need to composer dumpautoload everytime you create a new file.
So to create a new controller with the standard composer setup given by Laravel:
Create a new file in app/controllers named TemplateController.php
Open up terminal and run composer dumpautoload
As previous users have said, only view files should end with .blade.php.
If you're using Laravel 8, add this line to your RouteServiceProvider.php (you can search it by using CTRL + P):
protected $namespace = 'App\Http\Controllers';
This solved the issue for me.
It should be:
// File Name: TemplateController.php
class TemplateController extends BaseController {
public function index()
{
// return "made it"; // or
// app/views/myView.blade.php
return View::make('myView');
}
}
Route for that:
Route::get('mdpay/template', array("uses" => "TemplateController#index"));
Use blade in a Blade view, i.e: myView.blade.php basically stored in app/views/ folder. Read more about blate template on Laravel website.
Controllers live in the app/controllers directory and should remain there unless you have your own namespaced structure.
The reason you're getting a Class TemplateController does not exist is because it doesn't, firstly, your class is called templateController and secondly, it exists as templateController.blade.php which wouldn't be loaded in this way.
Blade files are for views, and only views within app/views or a custom views directory should end with .blade.php.
Create the file app/controllers/TemplateController.php and add the following code to it.
class TemplateController extends BaseController {
public function index()
{
echo "made it";
}
}
Now on the command line, run the command composer dumpautoload and change you route declaration to:
Route::get('mdpay/template', array('uses' => 'TemplateController#index"));
Now it should all work.
In case you're using Laravel 9 and the error is like Illuminate\Contracts\Container\BindingResolutionException and Target class <controller name> does not exist. when trying php artisan route:list on terminal.
This is the setup that I do:
Add protected $namespace = 'App\\Http\\Controllers'; to RouteServiceProvider.php
Add 'namespace App\Http\Controllers;' to the controller file.
Do php artisan optimize on terminal
(Just to make sure the route already there) Do php artisan route:list again on terminal, and the controller route should be displayed.