Where is better to place global variables at laravel? - laravel

I have to use global variables in some controllers and views, where is better to place them? At .env file or config/ files for example config/app.php?
Thanks.

global variable is a synonym for bad practice , i think you can't make it better
i also think that this question is opinion based.
anyway
why you dont do this
you can create a new controller lets say BaseController
BaseController extends Controller {
protected $hodor;
public function __construct()
{
$hodor = 'HOLD THE FREAKIN DOOR';
}
}
Then in your other controllers you can do this
MyOtherController extends BaseController {
public function hodor()
{
echo "today: $this->hodor";
}
}
But as i said Global variables are considered as bad practices so i think You should use sessions
i think you can use a config file or .env

Global variables are bad for sure. But using custom config is not the same as using global variables.
Create custom config file and put it under config directory. Then you'll be able to use config's variables from any part of your app:
$variable = config('configname.variablename');

Related

How to work with subdirectory controllers in CodeIgniter 4?

I need help with using sub directory controllers in CodeIgniter 4.
I just can't make it work for some reason.
This is the URL for example: www.example.com/admin/dashboard
In the controllers folder, I created a folder named Admin, and a file named Dashboard.php.
I used this code in Dashboard.php:
namespace App\Controllers;
class Dashboard extends BaseController
{
public function index()
{
}
}
I tried changing the class name to AdminDashboard, Admin_Dashboard, pretty much every logical name but every time I get a 404 error, saying:
Controller or its method is not found:
App\Controllers\Admin\Dashboard::index
I know the file itself gets loaded successfully, but I think I don't declare the classname correctly and it keeps throwing me those 404 errors.
The documentation of CI4 isn't providing any information about what the classname should be called unfortunately...
UPDATE #1
I managed to make it work by changing few things:
namespace App\Controllers\Admin;
use CodeIgniter\Controller;
class Dashboard extends Controller
{
public function index()
{
}
}
But now it won't extend the BaseController which has some core functions that I built for my app.
Any ideas to how to make it extend BaseController?
I must admit that I don't have much knowledge about namespacing yet, so that might be the reason for my mistakes.
As I imagined, the problem was that I didn't learn about namespacing.
I needed to point the use line at the BaseController location.
namespace App\Controllers\Admin;
use App\Controllers\BaseController;
class Dashboard extends BaseController
{
public function index()
{
}
}
Now www.example.com/admin/dashboard/ goes directly to that index function, as intended.
php spark make:controller /Subfolder/ControllerName
$routes->add('/(.+?)_(.+?)/(.+?)$', 'subdir\\\\$1_$2::$3');
$routes->add('/(.+?)_(.+?)$', 'subdir\\\\$1_$2::index');
I was able to map with this setting.
The route mapping could be as simple as:
$routes->group('admin', static function ($routes) {
$routes->get('dashboard', 'Admin\Dashboard::index');
});

How to set global variables from database in Laravel 5.4

I'm facing the same problem very often in various projects - I need to set some global variables from database and be able to receive them in anywhere in laravel - views, controllers, models. Is it possible? Or what is the most easy way to do this?
Why I need this? For language translations. I need them not cached and saved in file. For website options which can be taken from any place of app. For website language to set, because I don't want to make /language/ prefix on url.
Sorry if this question can be a duplicate, but none of the answers in similar questions worked in a way I have explained.
You can try view composers for sharing data globally to all views.
public function compose(View $view)
{
//get value from database
$options = Model::where('domain_name', \Request::server("SERVER_NAME"))->get();
//render to view
$view->with('options', $options);
}
The $options variable (model) would be available in every view.
To share data with all controllers define variables in base controller to access them in controllers which inherit base controller
class Controller extends BaseController
{
public $options = Model::where('domain_name', \Request::server("SERVER_NAME"))->get();
}
you can access it using
class LoginController extends Controller
{
public function dashboard()
{
//access here using
$x = $this->options;
}
}
Like this you can create a base model and use the inherit property to access data globally in models.
Hope it will be useful for you. The options variable may contain all the options from database.
Another way to do this is to create a helper class:
1> Add line to composer.json:
"autoload": {
"files": [
"app/Http/helpers.php"
],
2> Create file:
app/Http/helpers.php
3> Add code:
function o($code = null) {
$option = \Option::where('code', $code)->first();
return $option->value;
}
4> Use where you need:
echo o('option_code')
This works in Controller and View, before any render if called. Here can be checked session, config, cookies and etc.
the best way to access a variable everywhere in your project is using sessions. you can store everything in sessions and access it everywhere in your controllers, models and views.
Read the topic: https://laravel.com/docs/5.5/session#using-the-session

Laravel: Grab data from the Controller from inside a view composer

Atm I'm creating this view composer for fun. It is collecting .js filenames and then passing it to the layout to be linked. The filenames used depend on the current page. For example a lower ranked page like Slides, doesn't include ajax requests used in UserManagement. Please don't ask me why I would do this xD. Im planning to validate requests anyway. Just being bored.
Anyways, as I'm quite new to laravel I'm still looking for more efficient ways to do things.
Atm Im accessing the file names staticly. The Controller now looks like this
class Controller extends BaseController
{
public static $js_file_names = [];
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}
In the pagecontroller I construct the filenames:
class SlidesController extends Controller
{
public function __construct()
{
parent::$js_file_names = ['ccs', 'ajax-updates'];
}
And finaly I retreive them inside the registered Viewcomposer like this:
(during development $use_filenames has all files as default)
public function __construct()
{
$filenames = Controller::$js_file_names;
if( !empty($filenames) )
$this->use_filenames = $filenames;
var_dump($this->use_filenames);die;
}
It all seems to be working fine, but the big question is, is there a better way to access controller data from inside a viewcomposer? Every time I try to google this, I get results like 'passing data to views' etc, which is not rly the problem.
Update:
Another idea I had is to store all the filenames to be used in an array inside the viewcomposer itself, and check if the current page exists in that array. This would keep the controllers cleaner.
Using a view composer doesn't really make sense in this situation. Since your controllers already 'know' which files they intent to share, you may as well just pass them to the view like so:
class SlidesController extends Controller
{
public function __construct()
{
View::share('user_filenames', ['ccs', 'ajax-updates']);
}
}
A composer is more for sharing concrete elements such as collections of users, a service provider or some other class instance, for example.

Laravel Use a method from BaseController in a view

As I need to get for every page a site configurations variables from a table of my database called 'site_configuration', I use a method in my baseController :
In the __constructor i have
$this->config = SiteParameter::first();
and I have a public method to retrieve a variable :
public function getSiteParameter($variable)
{
return $this->config->$variable;
}
If I do $this->getSiteParameter('sitename') it works. I'd like to do the same thing in a view. but without passing values to the view. I'd be happy if it was automatic.
Use the controller __construct to share the config data with the view. E.g.:
public function __construct() {
View::share('config', $this->config);
}
Just use the Config class, as explained in the configuration documentation. To put it short, assuming you created a customer configuration file app/config/site.php:
<h1><?= Config::get('site.sitename') ?></h1>

Global Variables in CodeIgniter not Working

I want to generate global variables in CodeIgniter by creating my own library and config file. This is what I wrote ini my library file, let's say globalvars.php. I put it in /application/libraries.
class Globalvars{
function __construct($config = array())
{
foreach ($config as $key => $value) {
$data[$key] = $value;
}
$CI =& get_instance();
$CI->load->library('session');
$CI->load->vars($data);
}
}
I want the user id stored in the session to be available in global variable, so I wrote this in my config file. It's named also globalvars.php. It's in /application/config directory.
$config['user']=$this->session->userdata('id');
I then test to see if it's working by write it in my controller this way.
echo $data['user'];
But I get this error in the browser
Message: Undefined property: CI_Loader::$session
Filename: config/globalvars.php
It seems that the session functions is not defined yet. How can I get it work? What have I missed here? Any help would be appreciated.
You cannot use the session library in config file.
The config files are loaded before any libraries, so $this->session is undefined.
The config.php has to be loaded in order for the Session class to even be initialized, as it reads settings from that file.
A lot of issues with this type of thing (setting some "global" data) can be resolved using a base controller, and extending it in your controllers.
// core/MY_Controller.php
MY_Controller extends CI_Controller {
function __construct()
{
parent::__construct(); // Now the Session class should be loaded
// set config items here
}
}
"Normal" controllers will now extend MY_Controller to take advantage of this.
See: http://codeigniter.com/user_guide/general/core_classes.html for more details.
In addition, when you load->vars(), they are available to the view layer only, it does not create a global variable called $data as you seem to be trying to access. If you do this:
$this->load->vars(array('user' => '1'));
You would access it in a file loaded by $this->load->view() like this:
echo $user; // outputs "1"
See: http://codeigniter.com/user_guide/libraries/loader.html
$this->load->vars($array)
This function takes an associative array as input and generates
variables using the PHP extract function. This function produces the
same result as using the second parameter of the $this->load->view()
function above. The reason you might want to use this function
independently is if you would like to set some global variables in the
constructor of your controller and have them become available in any
view file loaded from any function. You can have multiple calls to
this function. The data get cached and merged into one array for
conversion to variables.
I will say that as an experienced Codeigniter user, the concept of a "global vars" class is a bit wonky and probably unnecessary, especially when it's already so easy to get and set config items. You could definitely run into some confusing issues and variable name conflicts with this method (pre-loading lots of view variables on every request).

Resources