I have tried to google out where i can store in Laravel static data ( just simple arrays ) but have not found any obvious reasons or explanations, just some existing solutions.
Data could be for example list of countries. Yes it could be stored in DB but it sounds for me useless since that data would be static and used only for retrieval puposes.
I have seen many approaches for storing data like this for example:
Models ( Entities )
Storing as package
Controllers
Is there any practises where to store such static data?
Or maybe "data" it self refers to store data where it should be belong, - database, no matter what operations would be done on it?
Laravel is opinionated, and you should be. There is more than one way to do it.
You can make it stay like a config, and query as a piece of config. For example: config/mydata.php (make sure to return an array), and then config()->get('mydata.***').
You can make a helper and register to autoloader, create app/helpers.php,
public function generate_data()
{
return [ 'x' , 'x' ,'x' ... ];
}
register via composer.json,
{
"autoload": {
"files": [
"app/helpers.php"
]
}
}
Well, if you need another obvious PHP style, create a file anywhere in root project, for example: MY_LARAVEL_PROJECT_ROOT/mydata/country.php, create the file and returning an array of your things. At the end of app/start/global.php, require it,
require base_path().'/mydata/country.php';
It just works like that and have fun :)
You can store static arrays and other constant variables in config/constants.php file...
Related
I have an application developed with Laravel. My software has settings that are used globally and should be available in all controllers (such as default information). I take this information from the database in the main controller every time a request is sent and save it in a variable.
namespace App\Http\Controllers;
class Controller extends BaseController
{
protected $config;
public function __construct()
{
$this->config= DB::table('config')->get();
}
}
Is there a way to save and use this information without the intervention of a database? I don't want to use sessions.
It is better if a solution is introduced using laravel packages.
Thanks
Assuming that you collection doesn't hold a lot of data, you can always put it inside your custom config. Create a php file inside your app/config directory, where you can put all your values like this:
<?php
return [
'key1' => value1,
'key2' => value2,
];
You can create any data structure here that you might need. Now, when you need to read single key from this data, you can use Laravel's config() helper:
$config = config('config_name.key');
If you want to get whole collection of the data, you can do it with the same config() helper, like this:
$config = config('app.config_name');
Hope that I understood your question right, and that this can lead you in right direction. You can read more about config on official documentation.
I've got a custom collection sortBy function that I use to sort a model. The problem is, I'm copying and pasting this filter code every time I want to sort it. It seems like this must be beyond best practices since copying and pasting code for reuse is a no no. What is the best practice way to handle this?
For instance, we have Eloquent scopes for reusable query based sorting and stuff like that, but nothing for collections along the same vein.
Declare a "helper" function (see Laravel's helpers for where to put this & how to autoload it) and use that wherever you need to sort, like this:
The sort function:
function mySortHelper($a, $b) {
// ... sorting code goes here ...
}
And when you need to use it:
$collection->sortBy("myHelperFunction");
Edit: Adding a helper function
Here's the way I've done this in my applications.
In the app directory, create a folder called Helpers.
Inside the Helpers directory, create a new PHP file called (for example) Sorting.php.
In this new file, create your function like this:
if ( ! function_exists('mySortHelper'))
{
function mySortHelper($a, $b)
{
return $a<$b ? -1 : 1;
}
}
This code is copied (with changes) from the the Laravel framework helpers file (found at vendor/laravel/framework/src/Illuminate/Foundation/helpers.php).
Then the only thing left is the autoloading. Update your composer.json file with:
"autoload": {
"files": [
...
"app/Helpers/Sorting.php",
...
]
},
There may be other sections in the autoload section of the composer.json or other things listed under files. Just add the file you created to that section of your composer.json and run composer dump-autoload to update. Your helper function will now be available throughout your Laravel application.
I'm working on an application written in PHP. I decided to follow the MVC architecture.
However, as the code gets bigger and bigger, I realized that some code gets duplicated in some cases. Also, I'm still confused whether I should use static functions when quering the database or not.
Let's take an example on how I do it :
class User {
private id;
private name;
private age;
}
Now, inside this class I will write methods that operate on a single user instance (CRUD operations). On the other hand, I added general static functions to deal with multiple users like :
public static function getUsers()
The main problem that I'm facing is that I have to access fields through the results when I need to loop through users in my views. for example :
$users = User::getUsers();
// View
foreach($users as $user) {
echo $user['firstname'];
echo $user['lastname'];
}
I decided to do this because I didn't feel it's necessary to create a single user instance for all the users just to do some simple data processing like displaying their informations. But, what if I change the table fields names ? I have to go through all the code and change those fields, and this is what bothers me.
So my question is, how do you deal with database queries like that, and is it fine to use static functions when querying the database. And finally, where is it logical to store those "displaying" functions like the one I talked about ?
Your approach seems fine, howerver I would still use caching like memcached to cache values and then you can remove static.
public function getUsers() {
$users = $cacheObj->get('all_users');
if ($users === false) {
//use your query to grab users and set it to cache
$users = "FROM QUERY";
$cacheObj->set('all_users', $users);
}
return $users;
}
(M)odel (V)iew (C)ontroller is a great choice choice, but my advice is look at using a framework. The con is they can have a step learning curve, pro is it does a lot of heavy lifting. But if you want to proceed on your own fair play, it can be tough to do it yourself.
Location wise you have a choice because the model is not clearly define:
You'll hear the term "business logic" used, basically Model has everything baring views and the controllers. The controllers should be lean only moving data then returning it to the view.
You model houses DB interaction, data conversions, timezone changes, general day to day functions.
Moudle
/User
/Model
/DB or (Entities and Mapper)
/Utils
I use Zend and it uses table gateways for standard CRUD to avoid repetition.
Where you have the getUsers() method you just pass a array to it, and it becomes really reusable and you'd just have different arrays in various controller actions and it builds the queries for you from the array info.
Example:
$data = array ('id' => 26)
$userMapper->getUsers($data);
to get user 26
enter code here
$data = array ('active' => 1, 'name' => 'Darren')
$userMapper->getUsers($data);`
to get active users named Darren
I hope this help.
I have just started playing with laravel haveing come from codeigniter and I am trying to work out the best way to define a series of constants.
CI uses a constants folder under app/config and I was largely happy with this approach for most things but wanted advice as to the best way to do this in Laravel.
My constants fall into 3 categories and I would like advice if possible on how best to store and retrieve each (baring in mind I'm completely new to Laravel.
Type 1:
Constants which need to be loaded everytime a controller is called:
e.g. I would like to start by defining a constant to tell me if the user is requesting content via ajax, this is what I used to do in CI constants file:
define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')
Type 2:
Constants which can be changed by the user:
Are these best stored in a database or would writing to a config file be a better option? Again looking for advice on how to store and retrieve
Type 3:
Constants which are only needed in specific controllers:
Ideally I would like to be able to group constants into arrays or separate files and pull them out in groups as required.
e.g. I could just retrieve my upload settings for my upload controller.
Thanks for any help/advice in advance - examples would be greatly appreciated
Type 1
You can add any constant in Bundle (or application) start.php file.
Type 2 and 3
I would suggest using Config for both these requirement.
My solution is create a file inside app/config folder called "constants.php"
app/config/constants.php
The code inside is in array way.
"some value",
'c2'=>"some value"
);
?>
then inside each controller you can retrieve using
Config::get('constants.c1');
I think is an easy way to do it, it's more scalable.
<?php
//file : app/config/constants.php
return [
'IS_AJAX' => isset($_SERVER['HTTP_X_REQUESTED_WITH']
];
in anywhere:
echo Config::get('constants.IS_AJAX');
So, I am looking at a number of ways to store my configuration data. I believe I've narrowed it down to 3 ways:
Just a simple variable
$config = array(
"database" => array(
"host" => "localhost",
"user" => "root",
"pass" => "",
"database" => "test"
)
);
echo $config['database']['host'];
I think that this is just too mutable, where as the configuration options shouldn't be able to be changed.
A Modified Standard Class
class stdDataClass {
// Holds the Data in a Private Array, so it cannot be changed afterwards.
private $data = array();
public function __construct($data)
{
// ......
$this->data = $data;
// .....
}
// Returns the Requested Key
public function __get($key)
{
return $this->data[$key];
}
// Throws an Error as you cannot change the data.
public function __set($key, $value)
{
throw new Exception("Tried to Set Static Variable");
}
}
$config = new stdStaticClass($config_options);
echo $config->database['host'];
Basically, all it does is encapsulates the above array into an object, and makes sure that the object can not be changed.
Or a Static Class
class AppConfig{
public static function getDatabaseInfo()
{
return array(
"host" => "localhost",
"user" => "root",
"pass" => "",
"database" => "test"
);
}
// .. etc ...
}
$config = AppConfig::getDatabaseInfo();
echo $config['host'];
This provides the ultimate immutability, but it also means that I would have to go in and manually edit the class whenever I wanted to change the data.
Which of the above do you think would be best to store configuration options in? Or is there a better way?
Of those 3 options, a static method is probably the best.
Really, though, "the best" is ultimately about what's easiest and most consistent for you to use. If the rest of your app isn't using any OO code then you might as well go with option #1. If you are ultimately wanting to write a whole db abstraction layer, option #2.
Without knowing something more about what your goals are and what the rest of your app looks like, it's kind of like asking someone what the best motor vehicle is -- it's a different answer depending on whether you're looking for a sports car, a cargo truck, or a motorcycle.
I'd go with whats behind door #3.
It looks easier to read and understand than #2, and seems to meet your needs better than #1.
Take a look at this question for ideas on storing the config data in a separate file:
Fastest way to store easily editable config data in PHP?
I'd use method #2 pulling the config data as an array from an external file.
The best way is that which fits your application best.
For a small app, it might be totally sufficient to use an array, even it is mutable. If no one is there to modify it except you, it doesn't have to be immutable.
The second approach is very flexible. It encapsulates data, but does not know anything about it. You can pass it around freely and consuming classes can take from it what they need. It is generic enough to be reused and it does not couple the config class to the concrete application. You could also use an interface with this or similar classes to allow for type hints in your method signatures to indicate a Config is required. Just don't name it stdDataClass, but name it by it's role: Config.
Your third solution is very concrete. It hardcodes a lot of assumptions about what your application requires into the class and it also makes it the responsibility of the class to know and provide this data through getters and setters. Depending on the amount of components requiring configuration, you might end up with a lot of specific getters. Chances are pretty good you will have to rewrite the entire thing for your next app, just because your next app has different components.
I'd go with the second approach. Also, have a look at Zend_Config, as it meets all your requirements already and let's you init the Config object from XML, Ini and plain arrays.