I have some php lines which will be used very often in my application. So I would like to build a function and call it every where in my app. My function could be :
static function array_matiere($id_ecole) {
return $something;
}
I tried to put this code in a controller and then call it like that :
$liste_matieres = MatieresController::array_matieres(Session::get('id_ecole'));
It works, but where to put this kind of function ? in the controller ? in a method file ? what is the best practice ?
Thanks for your responses.
Dominique
There are multiple ways to implement this. look here
Method 1 This method is highly suggested by Laravel Expert ( JeffreyWay)
If your helper functions are similar to the way laravel 5 ones work, i.e Illuminate/Support/helpers.php you could just create a helpers.php and have composer do the autoloading for you.
Edit your composer.json file and add the file to the autoloading key. In my example my app is called Tasky so just add the files key and reference helpers.php.
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"Tasky\\": "app/"
},
"files": [
"app/Support/helpers.php"
]
},
That way you just create your file inside app/Support/helpers.php and all your common function based view helpers or other helpers can go here. If you take the class based approach then the above is great.
Also then remember to just run the following once.
$ composer dumpautoload
Source
Method 2
Please Follow the link and read answer & Its comments
Whenever u need to include a piece of code providing some functionality through out your application then the best way in Laravel is to make Service class inside app/Services and then you can use that class anywhere in your application using
use App\Services\YourServiceName;
Related
Please, don't talk to technical in the answers:-D I am not a hardcore programmer.
What is a good way to store certain functions in Laravel? I have functions that apply on a "post" only or "media" only, like getAttributeList or getComponents. I say "Post" and "Media" because both have their own controller, model and views. It feels wrong to put it in the model because that should be database stuff right? And traits are more for recurring functions all over the place, right? So, right now I have one big file called Helpers.php. And uh, it is getting large... should I simply separate it in PostHelpers.php, MediaHelpers.php etc? Or is there a more elegant way in Laravel to do it?
It is quite simple : Just check your composer.json file at root directory of ur app. and under autoload section add :
"autoload": {
"psr-4": {
"App\\": "app/"
},
"files": ["app/helper.php"],
"classmap": [
"database/seeds",
"database/factories"
]
"files": ["app/helper.php"], This is the line you need to add in ur composer file and provide the path to file .
In my case i have created a file helper.php in App directory where i keep all my functions .
after this run this command :
composer dump-autoload
Now u can access your functions anywhere.
In your composer json file check this snippet
"autoload": {
"files": [
"app/Helpers/global_helper.php"
],
As you see I have auto loaded 1 single file called global_helper.php in a folder called Helpers Now in this file I have a function called loadHelper(...$files)
What this function does is
if (!function_exists('loadHelper')) {
function loadHelper(...$file_names)
{
foreach ($file_names as $file) {
include_once __DIR__ . '/' . $file . '_helper.php';
}
}
}
You can pass your file name as array or string and it will include those files into your Controller constructor
So In my Controller whenever I want some helper function I create a saperate helper file for that controller then in constructor i ust include it.
I am not sure if there is any better solution but so far this is how I am making all my projects .
I hope this will help you ;)
Actually, I am trying to define a constant and setting value from the session
in a custom helper added using Helper Service Provider. But not getting the session data in here.
I have added a Helper using Helper Service Provider, It's working fine.
But trying to get the session value.
In HelperServiceProvider.php
public function register()
{
foreach (glob(app_path().'/Helpers/*.php') as $filename){
require_once($filename);
}
}
And in ERPHelper.php in App/Helpers folder, I am trying to get the session data. But not getting the session value.
$company = session('company');
This is often down to the middleware. If you're setting the company session value under the web middleware, you might not be able to retrieve this is in a helper function registered by the service provider.
Also, out of interest, why are you setting this in a constant? It seems odd to me to use a the session helper to retrieve a value and then set it in a constant. A constant should probably not be used in this way but also you are adding an additional layer of abstraction. Why not just call session('company') as and when you need it?
I load in a helper Bootstrap.php via the composer.json file in the autoload section:
"autoload": {
"files": [
"app/Helpers/Bootstrap.php"
],
"psr-4": {
"App\\": "app/"
},
"classmap": [
"database"
]
},
Then in the Bootstrap.php you could run your glob to load the relevant files.
That said, this still might not help because you're outside the web middleware. Can you not pass the session value to your helper function?
// Helper function.
function myErpHelper($companySessionValue) {
// My code here...
}
// Calling the helper function.
myErpHelper(session('company'));
On the documentation for Slim Framework, it says
In this example application, all the routes are in index.php but in
practice this can make for a rather long and unwieldy file! It’s fine
to refactor your application to put routes into a different file or
files, or just register a set of routes with callbacks that are
actually declared elsewhere.
It doesn't say how to actually do this though. My only thought is that you could split code into multiple PHP files and then use include or require in index.php to reference these.
I'm also not sure what it means by "register a set of routes with callbacks that are actually declared elsewhere"
Does anyone have any thoughts on this, since the application I'm wanting to build might have quite a few routes?
Being a micro-framework, Slim does not enforce any specific method. You can either find a ready-to-use structure (Slim Skeleton Application comes to my mind) or write your own; unlike other frameworks, Slim does not try to protect you from PHP.
Route definitions can be something as simple as an array of strings:
<?php // routes.php
return [
'/' => ['Foo\\Home', 'index'],
'/about' => ['Foo\\Home', 'about'],
'/contact' => ['Foo\\Contact', 'form' ],
];
... which you then load and process in your index.php entry point:
$routes = require('/path/to/routes.php');
foreach ($routes as list($path, $handler)) {
$app->get($route, $handler);
}
And you can leverage the existing Composer set up to auto-load your classes by adding the appropriate directories to composer.json:
{
"require": {
"slim/slim": "^3.3",
"monolog/monolog": "^1.19"
},
"autoload": {
"psr-4": {"Foo\\": "./Foo/"}
}
}
From here, it can get as complex as required: define routes in a YAML file, auto-load from defined classes, etc.
(Code samples are shown for illustration purposes and might not even be valid.)
There're some thoughts on it in Slim documentation
Instead of require's you can use composer autoloading
"register a set of routes with callbacks that are actually declared elsewhere"
From docs:
Each routing method described above accepts a callback routine as its final argument. This argument can be any PHP callable...
So you can do:
$routeHandler = function ($request, $response) { echo 'My very cool handler'; };
$app->get('/my-very-cool-path', $routeHandler);
But usually people use classes instead of functions:
http://www.slimframework.com/docs/objects/router.html#container-resolution
I think you almost get the basic idea right. I recommend reading chapter on routing a couple of times. It covers everything pretty good.
Happy coding and let me know if you need any other help!
I wrote a REST API with Laravel. On top of that i want to create an admin panel with a lot of statistics and "mighty" moderation tools which should render on server-side.
While the REST API uses OAuth2.0 and only returns JSON+HAL (HATEOAS), the admin panel would use a HTTP Basic auth plus a normal credential login with session based authentication.
I know it would be easily possible to use a second auth-filter and Route groups to make all this happening in one application. And i know that libs are only loaded if needed. But i want to create a second application which is completely independent.
Why?
To keep the REST API lightweight: No unnecessary libraries, no second auth-layer, no additional routes, rules and filters, etc. The REST API is Restful and i do not want to add additional clutter. Though it might make testing a little bit more complicated.
Here is how it should look like:
backend
rest (Laravel application 1)
-- app
--- models
---- RestapiModel.php
admin (Laravel application 2)
-- app
--- models
---- AdminModel.php
The problem is: In application 2 i need to work with models of application 1
So i would like to do s.th. like
class AdminModel extends RestapiModel {
protected $connection = 'application_1_database';
// Statistical methods
// Database manipulation
// etc.
}
I now have two questions:
How can i make this possible? "AdminModel extends RestapiModel" won't work. Do i have to use namespaces, traits or just include the Model on top of the file? How would you solve this?
What do you think about the complete approach to separate API and administration?
Thanks in advance
Phil
It's not pretty but you can use require to import the file(s)
require base_path().`/../rest/models/RestapiModel.php`;
class AdminModel extends RestapiModel {
protected $connection = 'application_1_database';
// Statistical methods
// Database manipulation
// etc.
}
Or you can autload all the models of the rest api using composer. Your composer.json in the admin application could look like this:
// ...
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"../../rest/app/models",
"app/database/migrations",
// ...
]
},
// ...
(After changing the autoload section make sure to run composer dump-autoload)
I am wondering where to put the Laravel Event Listeners and Handlers. Somebody told me that I can put them anywhere. This is what I have tried so far.
# listeners/log.php
<?php
Event::listen('log.create', 'LogHandler#create');
# handlers/LogHandler.php
<?php
class LogHandler {
public function create(){
$character = new Character;
$character->name = "test";
$character->save();
}
}
# controllers/MainController.php
public function test(){
Event::fire('log.create');
return "fired";
}
# start/global.php
ClassLoader::addDirectories(array(
app_path().'/commands',
app_path().'/controllers',
app_path().'/models',
app_path().'/database/seeds',
app_path().'/libraries',
app_path().'/listeners',
app_path().'/handlers',
));
I'm going to assume that you're asking this because they're not working, rather than for confirmation of something that you've got working.
Whilst it is correct that you can put event listeners anywhere, you need to make sure they'll actually get included - Laravel doesn't search through your source code looking for them.
My favourite place to include such files is in start/global.php. If you look at the bottom of the file you can see where the filters are included, you can do the same to include your listeners. It would be cleanest to keep them all in one listeners file, like all of your routes are in one routes file...
# start/global.php
require app_path().'/filters.php';
My personal opinion is that it's bad practice in general to lump event listeners in a single place. Sure, today you only need 2 or 3, but scope can be added to any project at any time, possible adding a lot more.
Instead, I generally create a directory underneath the app directory (e.g. app/CompanyName) and put all of my application specific code in there. To tell Laravel how to find your files, you can then update your composer.json llike this:
"autoload": {
"classmap": [
// ...
],
"psr-4": {
"CompanyName\\" : "app/"
},
}
After that, be sure to run composer dump-autoload.
Now, you can create namespace directories inside of your custom application directory, like app/CompanyName/Events/, and be able to segregate out your event listeners into groups that make sense, and put them inside of a service provider, for example:
<?php namespace CompanyName/Events;
// File: app/CompanyName/Events/LogEventsProvider.php
use Illuminate\Support\ServiceProvider;
class LogEventsProvider extends ServiceProvider
{
public function register()
{
Event::listen('log.create', 'CompanyName/Events/LogEventsProvider#create');
}
public function create()
{
// ...
}
}
Now you can add this service provider to your app/config/app.php and be good to go, and have all of your related event listeners in a single file, and ALL of your event listeners in a single directory, yet separate so that if something goes wrong with one of them you don't have to search through ALL of them to find where the error is happening.
NB: I did not come up with this as a practice, but found it somewhere along the way. I however cannot remember where it was.