أفضل حل لـ "صفيف التسلسل"
-
03-10-2019 - |
سؤال
لمشروعي ، كتبت فئة تكوين صغيرة تقوم بتحميل بياناتها من ملف .ini. يكتب طريقة Magic __get () من أجل توفير وصول مبسط إلى قيم التكوين (قراءة فقط).
مثال config.ini.php:
;<?php exit; ?>
[General]
auth = 1
user = "halfdan"
[Database]
host = "127.0.0.1"
يبدو فئة التكوين الخاصة بي (نمط المفرد - مبسط هنا) هكذا:
class Config {
protected $config = array();
protected function __construct($file) {
// Preserve sections
$this->config = parse_ini_file($file, TRUE);
}
public function __get($name) {
return $this->config[$name];
}
}
من شأن تحميل التكوين إنشاء بنية صفيف مثل هذا:
array(
"General" => array(
"auth" => 1,
"user" => "halfdan"
),
"Database" => array(
"host" => "127.0.0.1"
)
)
من الممكن الوصول إلى المستوى الأول من المصفوفة من خلال القيام به Config::getInstance()->General
, والقيم باستخدام Config::getInstance()->General['user']
. ما أريده حقًا هو القدرة على الوصول إلى جميع متغيرات التكوين من خلال القيام بذلك Config::getInstance()->General->user
(التجميل اللغوى). الصفيف ليس كائنًا ولا يتم تعريف "->" ، لذلك يفشل هذا ببساطة.
فكرت في حل وأرغب في الحصول على بعض الرأي العام حول هذا الموضوع:
class Config {
[..]
public function __get($name) {
if(is_array($this->config[$name])) {
return new ConfigArray($this->config[$name]);
} else {
return $this->config[$name];
}
}
}
class ConfigArray {
protected $config;
public function __construct($array) {
$this->config = $array;
}
public function __get($name) {
if(is_array($this->config[$name])) {
return new ConfigArray($this->config[$name]);
} else {
return $this->config[$name];
}
}
}
هذا من شأنه أن يسمح لي بسلسلة وصول التكوين الخاص بي. نظرًا لأنني أستخدم PHP 5.3 ، فقد تكون أيضًا فكرة جيدة للسماح لـ Configarray بتمديد ArrayObject (يتم تنشيط SPL لكل افتراضي في 5.3).
أي اقتراحات ، والتحسينات ، والتعليقات؟
المحلول
إذا كانت عناصر الخاص بك $this->config
الصفيف هي أيضا مثيلات لك Config
الفصل ، ثم يعمل.
ال Zend Framework لديه مكون مماثل يسمونه Zend_Config. تستطيع تحميل المصدر وفحص كيفية تنفيذه. لم يكن عليهم أن يذهبوا على طول الطريق للتمديد ArrayObject
.
ال zend_registry الفصل لديه استخدام مماثل ويمتد ArrayObject
. رمز zend_registry أبسط إلى حد ما نتيجة لذلك.
نصائح أخرى
إذا كنت تريد تسلسل صفيف في PHP ، فيجب عليك إلقاء نظرة على سلسلة. إنه مشروع صغير حقًا إذا كان بإمكانك استخدام طرق التسلسل مثل filter
و count
مثلك ترميز جافا!
$arr = array_filter(
array_map(
function ($v) { return rand(0, $v); },
array_fill(0, 10, 20)
),
function ($v) { return $v & 1; }
);
يصبح
$chain = Chain::fill(0, 10, 20)
->map(function ($v) { return rand(0, $v); })
->filter(function ($v) { return $v & 1; });
رائع أليس كذلك؟ مزيد من المعلومات التي يمكنك العثور عليها هذه المدونة.