I want a variable to be shared by other controller methods. This variable can be updated by one controller method and the change should be reflected in other methods? any suggestions ? what is the best practice to do that ? this is my code:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use Session;
class test extends Controller
{
public $global;
public function __construct()
public function a(Request $request){
$this->global="some value"
}
public function b(Request $request){
echo $this->global;
//it always return a null
}
}
Set the variable inside your constructor.
function _construct() { $this->global = "some value";}
So, you don't only want a global variable, you also want that this variable should be changed by other routes as well. The one way to achieve this is using session.
function a() {
session()->put('global_variable', 'set by method a');
//your other logic
}
and from method b...
function b() {
//get the variable set by method a here
dd(session()->get('global_variable'));
}
You can create a new file in config and use
config('your_new_file_name.key')
Check this : https://laracasts.com/discuss/channels/general-discussion/laravel-5-global-variables
Related
I have and function like this, and I am using this through API and send request object.
public function test(Request $request){
//code
}
now I want to use the same function in another function like this
public function test2(){
$id = 2;
$this->test($id);
}
but in above I need to pass an id.
but the first function expects an argument type of request instance.
How can it be done? and I can't add second argument.
If you are not allowed to edit the method code for some reason, you can do the following:
Create a new Request instance.
Add id property to it with the value.
Call your method.
The Illuminate\Http\Request class has a capture() method which is like below:
/**
* Create a new Illuminate HTTP request from server variables.
*
* #return static
*/
public static function capture()
{
static::enableHttpMethodParameterOverride();
return static::createFromBase(SymfonyRequest::createFromGlobals());
}
In your code, you would do like below:
<?php
use Illuminate\Http\Request;
class xyz{
public function test(Request $request){
//code
}
public function test2(){
$request = Request::capture();
$request->initialize(['id' => 2]);
$this->test($request);
}
}
You should export your code in another function and then use a Trait in each of your controller. Therefore you will have access to the same function in two different classes.
By doing this, you can give whatever argument you want, even set defaults one without calling the controller function itself.
The official doc about Trait
The best practice would be to create a third private method in the controller (or in a separate class, as you prefer) that is called by both functions:
class TestController extends Controller {
public function test(Request $request){
$id = $request->get('id', 0); // Extract the id from the request
$this->doStuffWithId($id);
}
public function test2(){
$id = 2;
$this->doStuffWithId($id);
}
private function doStuffWithId($id) {
// code
}
}
You can and should organize your shared code across multiple controllers with services. Basically create class
<?php
namespace App\Services;
class TestService
{
public function testFunction($id)
{
// add your logic hear
return 'executed';
}
}
and in your controller inject this service and call function testFunction() like this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Services\TestService;
class TestController
{
protected $testService;
public function __construct(TestService $testService)
{
$this->testService = $testService;
}
public function test(Request $request){
// handle validation, get id
$this->testService->testFunction($id);
// return response from controller (json, view)
}
I want to fetch user based on id but it's returning null but User::all() is working correctly.
index and show methods in UsersController :-
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
use DB;
class UsersController extends Controller
{
public function __construct()
{
$this->middleware('auth',['except'=>['index','show']]);
}
public function index()
{
$users=User::all();
return view('dev.index')->with('users',$users);
}
public function show(User $user)
{
return view('dev.show')->with('user',$user);
}
}
Route:-
Route::resource('devs','UsersController');
On view I have {{dd($user->name)}} and it's returning null on url public/devs/{dev}.
but working fine on index on url public/devs
This is because you are defining your base route like this:
Route::resource('devs', 'UserController');
This means that laravel will format the show method as follows:
Route::get('devs/{dev}', 'UserController#show');
Laravel will try to solve this dependency doind Implicit Model Binding and given that {dev} doesn't match any of your defined model classes, it will indeed return null.
So to solve it, define this match explicitly doing Explicit Binding. To accomplish this, go to your:
App/Providers/RouteServiceProvider.php
public function boot()
{
parent::boot();
Route::model('dev', App\User::class);
}
So now wherever Laravel reads the {dev} route parameter, will match it with the User model.
You don't initialize users for your entire controller.
Each function uses their own variables
First of all, I would reconfigure your route like so:
Route::get('devs', 'UsersController#show')->name('showUsers')
In your function show I would do the following
public static function show(){
$id = 1;
$users = User::where('id', $id')
return view('dev.show', compact('users'));
}
We want to pass data from controller to another controller in Laravel (framework). In our Controller.php we got a middleware code in the __construct function, which sets a environment and person.
Code in Controller.php
public function __construct()
{
$this->middleware(function ($request, $next) {
$this->environment = session()->get('environment');
$this->person = session()->get('person');
return $next($request);
});
}
In a different controller we pass 2 parameters (Request data) and (id of data) to another controller function. We tried many ways for pass data. On this moment we lost our $this data like environment and person, the variables environment and person are exists but empty.
We tried with:
$postController = new \App\Http\Controllers\Publication\Post\IndexController();
$postController->duplicate($request, data_get($publication, 'id'));
Or
app('App\Http\Controllers\Publication\Post\IndexController')->duplicate($request, data_get($publication, 'id'))
In Post\IndexController#duplicate we lose our $this data (empty).
We tried to get data like $this->enviroment but this variables are empty.
Anyone has any idea how to pass data with the variables filled by the middleware?
You can use the power of Container
Code in Controller.php
public function __construct()
{
$this->middleware(function ($request, $next) {
app()->instance('person', session()->get('person'));
app()->instance('environment', session()->get('environment'));
return $next($request);
});
}
In another controller:
<?php
namespace App\Http\Controllers;
class DupeController extends Controller
{
public function index()
{
dd(app('person'));
}
}
Just make sure if the "another controller" has it's own constructor, call the parent constructor, you your 'person' and 'environment' instance would be available in that controller.
<?php
namespace App\Http\Controllers;
class DupeController extends Controller
{
public function __construct()
{
parent::__construct();
// DO MAGIC
}
public function index()
{
dd(app('person'));
}
}
But I gotta tell you the truth, this is a bad practice. I just want to show you that something bad like this is possible. Try another approach like service injection to the controller using dependency injection technique and mark that service as a singleton, so container will resolve the same instance for every resolution (one instance per request).
I have controller class in laravel in which i have a function create() and a variable attachment i am calling function by ajax
my class code is.
class AttachmentController extends Controller
{
public $_attachments;
public function create()
{
$this->_attachments[]= 'test';
var_dump($this->_attachments);
}
problem is every time when i call it by ajax it return me "test" at 0 index of attachment array . but i want if i call create function 1st time it give me test on 0 index but when next time when i call it . it give me "test" on both 0 and 1 index and so on ..
how it is possible please help me
To preserve the values between requests you need to store them somewhere, an alternative is to use sessions, as the example below, for more information see https://laravel.com/docs/session
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class AttachmentController extends Controller
{
public function create(Request $request)
{
$request->session()->push('attachments', 'test');
var_dump($request->session()->get('attachments'));
}
}
Try something like this.
$_attachments[] = Session::get('test');
$_attachments[] = 'test';
Session::get('test', $_attachments);
dd(Session::get('test'));
let me know if this is what you want.
Since HTTP driven applications are stateless, sessions provide a way
to store information about the user across requests.
class AttachmentController extends Controller
{
public function create()
{
$attachments = Session::get('attachments', array());
$attachments[] = 'test';
Session::put($attachments);
var_dump($this->_attachments);
}
}
Further reading: Laravel Session
I have been facing a problem of not able to use the model inside the controller in the new laravel framework version 5. i created the model using the artisan command
"php artisan make:model Authentication" and it created the model successfully inside the app folder, after that i have created a small function test in it, and my model code looks like this.
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Authentication extends Model {
protected $table="canteens";
public function test(){
echo "This is a test function";
}
}
Now i have no idea, that how shall i call the function test() of model to my controller , Any help would be appreciated, Thanks in advance.
A quick and dirty way to run that function and see the output would be to edit app\Http\routes.php and add:
use App\Authentication;
Route::get('authentication/test', function(){
$auth = new Authentication();
return $auth->test();
});
Then visit your site and go to this path: /authentication/test
The first argument to Route::get() sets the path and the second argument says what to do when that path is called.
If you wanted to take this further, I would recommend creating a controller and replacing that anonymous function with a reference to a method on the controller. In this case, you would change app\Http\Routes.php by instead adding:
Route::get('authentication/test', 'AuthenticationController#test');
And then use artisan to make a controller called AuthenticationController or create app\Http\Controllers\AuthenticationController.php and edit it like so:
<?php namespace App\Http\Controllers;
use App\Authentication;
class AuthenticationController extends Controller {
public function test()
{
$auth = new Authentication();
return $auth->test();
}
}
Again, you can see the results by going to /authentication/test on your Laravel site.
Use scope before method name
<?php
namespace App\Models;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\Model;
class Mainmenu extends Model
{
public function scopeLeftmenu() {
return DB::table('mainmenus')->where(['menu_type'=>'leftmenu', menu_publish'=>1])->orderBy('menu_sort', 'ASC')->get();
}
}
above code i tried to access certain purpose to call databse of left menu
than we can easy call it in Controller
<?php
Mainmenu::Leftmenu();
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Authentication extends Model {
protected $table="canteens";
public function scopeTest(){
echo "This is a test function";
}
}
Just prefix test() with scope. This will become scopeTest().
Now you can call it from anywhere like Authentication::Test().
For me the fix was to set the function as static:
public static function test() {..}
And then call it in the controller directly:
Authentication::test()
You can call your model function in controller like
$value = Authentication::test();
var_dump($value);
simply you can make it static
public static function test(){
....
}
then you can call it like that
Authentication::test();
1) First, make sure your Model is inside a Models Folder
2) Then supposing you have a model called Property inside which you have a method called returnCountries.
public function returnCountries(){
$countries = Property::returnCountries();
}
of course, in your case, replace Property by the name of your Model, and returnCountries by the name if your function, which is Test
and in the Model you write that function requesting the countries
so in your Model, place a:
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Authentication extends Model {
protected $table="canteens";
public function test(){
return $test = "This is a test function";
}
}
and this is what your Controller will be getting
You should create an object of the model in your controller function then you can model functions inside your controller as:
In Model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Authentication extends Model {
protected $table="canteens";
public function test(){
return "This is a test function"; // you should return response of model function not echo on function calling.
}
}
In Controller:
namespace App\Http\Controllers;
class TestController extends Controller
{
// this variable is used to store authenticationModel object
protected $authenticationModel;
public function __construct(Request $request)
{
parent::__construct($request);
$this->authenticationModel= new \App\Authentication();
}
public function demo(){
echo $this->authenticationModel->test();
}
}
Output:
This is a test function