I'm learning PHP and I know too many ways to configure the application.
I use this method:
Folder:
- app
- config
- app.php
- db.php
- src
- class.php
- index.php
File:
// app.php
return [
'environment' => 'development',
'meta' => [
'description' => 'Description',
'title' => 'Title'
],
..
];
// db.php
return [
'connection' => 'mysql',
..
];
And some class for configuration:
namespace App;
use Closure;
class Singleton
{
private static $instance = [];
public static function get($name)
{
$instance = self::$instance[$name];
if ($instance instanceof Closure) {
$instance = $instance();
}
return $instance;
}
public static function set($name, $instance)
{
if (is_string($instance)) {
$instance = new $instance();
}
self::$instance[$name] = $instance;
}
private function __clone() {}
private function __construct() {}
private function __wakeup() {}
}
class Config
{
public static $data = [];
public static function forget($key)
{
Arr::forget(self::$data, $key);
}
public static function get($key, $default = null)
{
$segment = explode('.', $key);
if (! array_key_exists($file = current($segment), self::$data)) {
if (is_readable($path = 'app' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . $file . '.php')) {
self::$data[$file] = require_once $path;
}
}
return Arr::get(self::$data, $key, $default);
}
public static function set($key, $value)
{
Arr::set(self::$data, $key, $value);
}
public static function __callStatic($method, $argument)
{
$key = $method;
$default = null;
if (count($argument)) {
$key .= '.' . array_shift($argument);
$default = array_shift($argument);
}
return self::get($key, $default);
}
public function __call($method, $argument)
{
return self::__callStatic($method, $argument);
}
}
class Arr
{
public static function forget(&$array, $key)
{
$temp = &$array;
foreach ((array) $key as $path) {
$segment = explode('.', $path);
while (count($segment) > 1) {
$part = array_shift($segment);
if (self::has($array, $part)) {
$array = &$array[$part];
}
}
unset($array[array_shift($segment)]);
$array = &$temp;
}
}
public static function get($array, $key, $default = null)
{
if (is_null($key)) {
return $array;
}
if (array_key_exists($key, $array)) {
return $array[$key];
}
foreach (explode('.', $key) as $segment) {
if (! is_array($array) || ! array_key_exists($segment, $array)) {
return $default;
}
$array = $array[$segment];
}
return $array;
}
public static function has($array, $key)
{
if (empty($array) || is_null($key)) {
return false;
}
if (array_key_exists($key, $array)) {
return true;
}
foreach (explode('.', $key) as $segment) {
if (! is_array($array) || ! array_key_exists($segment, $array)) {
return false;
}
$array = $array[$segment];
}
return true;
}
public static function set(&$array, $key, $value)
{
if (is_null($key)) {
return $array = $value;
}
$data = explode('.', $key);
while (count($data) > 1) {
$key = array_shift($data);
if (! is_array($array) || ! array_key_exists($key, $array)) {
$array[$key] = [];
}
$array = &$array[$key];
}
$array[array_shift($data)] = $value;
return $array;
}
}
This is how it works:
function app($key = null, $default = null) {
App\Singleton::set('config', 'App\Config');
return $key ? App\Singleton::get('config')->get('app.' . $key, $default) : App\Singleton::get('config');
}
echo app('environment');
echo app('domain', 'http://domain.com');
echo app('meta.title');
echo app()->db('connection');
How it should be? Is this the best way?