Pengantar
Saya pikir Mengevaluasi Kueri JSON seperti MongoDB di PHP telah memberikan semua Informasi yang Anda butuhkan. yang Anda butuhkan hanyalah berkreasi dengan solusi dan Anda mencapai apa yang Anda inginkan
Array
Mari kita asumsikan kita memiliki json
yang mengikuti dikonversi ke larik
$json = '[{
"name":"Mongo",
"type":"db",
"release":{
"arch":"x86",
"version":22,
"year":2012
}
},
{
"name":"Mongo",
"type":"db",
"release":{
"arch":"x64",
"version":21,
"year":2012
}
},
{
"name":"Mongo",
"type":"db",
"release":{
"arch":"x86",
"version":23,
"year":2013
}
},
{
"key":"Diffrent",
"value":"cool",
"children":{
"tech":"json",
"lang":"php",
"year":2013
}
}
]';
$array = json_decode($json, true);
Contoh 1
periksa apakah key
- Different
akan sesederhana
echo new ArrayCollection($array, array("key" => "Diffrent"));
Keluaran
{"3":{"key":"Diffrent","value":"cool","children":{"tech":"json","lang":"php","year":2013}}}
Contoh 2 Periksa apakah release year
adalah 2013
echo new ArrayCollection($array, array("release.year" => 2013));
Keluaran
{"2":{"name":"Mongo","type":"db","release":{"arch":"x86","version":23,"year":2013}}}
Contoh 3
Hitung di mana Year
adalah 2012
$c = new ArrayCollection($array, array("release.year" => 2012));
echo count($c); // output 2
Contoh 4
Mari kita ambil contoh di mana Anda ingin memeriksa version
apakah grater than 22
$c = new ArrayCollection($array, array("release.version" => array('$gt'=>22)));
echo $c;
Keluaran
{"2":{"name":"Mongo","type":"db","release":{"arch":"x86","version":23,"year":2013}}}
Contoh 5
Periksa apakah release.arch
nilainya IN
satu set seperti [x86,x100]
(Contoh)
$c = new ArrayCollection($array, array("release.arch" => array('$in'=>array("x86","x100"))));
foreach($c as $var)
{
print_r($var);
}
Keluaran
Array
(
[name] => Mongo
[type] => db
[release] => Array
(
[arch] => x86
[version] => 22
[year] => 2012
)
)
Array
(
[name] => Mongo
[type] => db
[release] => Array
(
[arch] => x86
[version] => 23
[year] => 2013
)
)
Contoh 6
Menggunakan
. yang Dapat Dipanggil$year = 2013;
$expression = array("release.year" => array('$func' => function ($value) use($year) {
return $value === 2013;
}));
$c = new ArrayCollection($array, $expression);
foreach ( $c as $var ) {
print_r($var);
}
Keluaran
Array
(
[name] => Mongo
[type] => db
[release] => Array
(
[arch] => x86
[version] => 23
[year] => 2013
)
)
Contoh 7
Daftarkan nama ekspresi Anda sendiri
$c = new ArrayCollection($array, array("release.year" => array('$baba' => 3)), false);
$c->register('$baba', function ($a, $b) {
return substr($a, - 1) == $b;
});
$c->parse();
echo $c;
Keluaran
{"2":{"name":"Mongo","type":"db","release":{"arch":"x86","version":23,"year":2013}}}
Kelas Digunakan
class ArrayCollection implements IteratorAggregate, Countable, JsonSerializable {
private $array;
private $found = array();
private $log;
private $expression;
private $register;
function __construct(array $array, array $expression, $parse = true) {
$this->array = $array;
$this->expression = $expression;
$this->registerDefault();
$parse === true and $this->parse();
}
public function __toString() {
return $this->jsonSerialize();
}
public function jsonSerialize() {
return json_encode($this->found);
}
public function getIterator() {
return new ArrayIterator($this->found);
}
public function count() {
return count($this->found);
}
public function getLog() {
return $this->log;
}
public function register($offset, $value) {
if (strpos($offset, '$') !== 0)
throw new InvalidArgumentException('Expresiion name must always start with "$" sign');
if (isset($this->register[$offset]))
throw new InvalidArgumentException(sprintf('Expression %s already registred .. Please unregister It first'));
if (! is_callable($value)) {
throw new InvalidArgumentException(sprintf('Only callable value can be registred'));
}
$this->register[$offset] = $value;
}
public function unRegister($offset) {
unset($this->register[$offset]);
}
public function parse() {
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($this->array));
foreach ( $it as $k => $items ) {
if ($this->evaluate($this->getPath($it), $items)) {
$this->found[$it->getSubIterator(0)->key()] = $this->array[$it->getSubIterator(0)->key()];
}
}
}
private function registerDefault() {
$this->register['$eq'] = array($this,"evaluateEqal");
$this->register['$not'] = array($this,"evaluateNotEqual");
$this->register['$gte'] = array($this,"evaluateGreater");
$this->register['$gt'] = array($this,"evaluateGreater");
$this->register['$lte'] = array($this,"evaluateLess");
$this->register['$lt'] = array($this,"evaluateLess");
$this->register['$in'] = array($this,"evalueateInset");
$this->register['$func'] = array($this,"evalueateFunction");
$this->register['$fn'] = array($this,"evalueateFunction");
$this->register['$f'] = array($this,"evalueateFunction");
}
private function log($log) {
$this->log[] = $log;
}
private function getPath(RecursiveIteratorIterator $it) {
$keyPath = array();
foreach ( range(1, $it->getDepth()) as $depth ) {
$keyPath[] = $it->getSubIterator($depth)->key();
}
return implode(".", $keyPath);
}
private function checkType($a, $b) {
if (gettype($a) != gettype($b)) {
$this->log(sprintf("%s - %s is not same type of %s - %s", json_encode($a), gettype($a), json_encode($b), gettype($b)));
return false;
}
return true;
}
private function evaluate($key, $value) {
$o = $r = 0; // Obigation & Requirement
foreach ( $this->expression as $k => $options ) {
if ($k !== $key)
continue;
if (is_array($options)) {
foreach ( $options as $eK => $eValue ) {
if (strpos($eK, '$') === 0) {
$r ++;
$callable = $this->register[$eK];
$callable($value, $eValue) and $o ++;
} else {
throw new InvalidArgumentException('Missing "$" in expession key');
}
}
} else {
$r ++;
$this->evaluateEqal($value, $options) and $o ++;
}
}
return $r > 0 && $o === $r;
}
private function evaluateEqal($a, $b) {
return $a == $b;
}
private function evaluateNotEqual($a, $b) {
return $a != $b;
}
private function evaluateLess($a, $b) {
return $this->checkType($a, $b) and $a < $b;
}
private function evaluateGreater($a, $b) {
return $this->checkType($a, $b) and $a > $b;
}
private function evalueateInset($a, array $b) {
return in_array($a, $b);
}
private function evalueateFunction($a, callable $b) {
return $b($a);
}
}
Ringkasan
Ini mungkin tidak mencakup semua fitur lanjutan, dan harus memiliki arsitektur yang dapat diperluas
Kelas di atas menunjukkan contoh khas dari apa yang Anda inginkan .. Anda dapat dengan mudah decouple
it , perluas untuk mendukung ekspresi majemuk seperti $and
dan $or
Objek ekspresi kueri seperti MongoDB mudah untuk dipahami dan digunakan, memberikan kemampuan untuk menulis kode yang jelas dan bersih, karena kueri dan objek untuk ditelusuri, adalah array asosiatif.
Mengapa tidak menulis saja array ke MongoDB
database daripada mengerjakannya dengan array ?? Ini lebih efisien dan akan menghemat banyak masalah
Saya juga harus menyebutkan bahwa menggunakan alat terbaik untuk pekerjaan terbaik ... Apa yang Anda inginkan pada dasarnya adalah fungsi dari Database
Pada dasarnya berbicara dengan fungsi yang mudah untuk mengekstrak informasi dari array php. Mengetahui struktur array(arrayPath), ini akan memungkinkan untuk melakukan operasi pada data array multidimensi, tanpa perlu beberapa loop bersarang.
Contoh menunjukkan bagaimana menggunakan jalur untuk mencari nilai tetapi Anda masih bergantung pada pemuatan larik ke memori dan kelas Anda melakukan beberapa rekursi dan loop yang tidak seefisien database .
Saya menghargai tips arsitektur, kode terkait atau serupa, yang mungkin merupakan contoh praktik yang baik untuk membangun ekspresi "if..else" php dengan cepat.
Apakah Anda benar-benar ingin semua itu ada di sini ???