OOP PHP - Dinamik build / run nesne ve fonksiyon isimleri

3 Cevap php

Ben bir "en iyi uygulama" soru var. PHP bir OO MVC framework geliştiriyorum ve sınıfların en kolay etkileşim - Onlar tam anlamıyla kodu beyan ve kullanılmaktadır. Örneğin:

// In class 'getDetails'
$db = new mysqli(.....);
$db->query(.....);

Ancak, sınıf ve fonksiyon isimleri dinamik olarak inşa zamanlar vardır. Gerçek sınıf dosyaları tüm oluşturulur ve yerde çerçevesinde yer alan, ama hepsi tam anlamıyla beyan ve kullanılmaz vardır. Bu çerçeve bu isteği tamamlamak için ihtiyaç duyduğu sınıf bilir çalışma süresi kadar değil; yani sınıf ve fonksiyon isimleri genellikle oluşturulmuş ve değişkenler saklanır. En basit durumda, değişken bir nesne oluşturmak ve bir fonksiyonu çalıştırmak için kullanılır. Örnek:

$request = 'blog'; 
$action = 'view';
$class = new $request(); // Creates an blog object
$class->$action(); // Runs the blog function view

Değişkenler değişmez kullanım
here yığın taşması soru ve cevap) çalıştırmak için değişkenleri kullanmaya çalışırken Ancak, zaten /> bir durum içine çalıştırmak ($ istek :: $ action () Ayrıştırma hataları verir). Ben sınıfları, işlevleri ve nesneleri kullanarak / etkileşim için PHP manuel fonksiyonları gördük, ama önce onlarla uğraşmak zorunda değil.

Benim soru sınıfları ve sınıf ve fonksiyon isimleri anında oluşturulan fonksiyonları işlemek ve çalıştırmak için en iyi yolu nedir nedir?

3 Cevap

Bahsettiğiniz her iki yöntem de iyi ancak bazı sınırlamaları vardır:

Normal gösterimi kullanarak:

$request = 'blog'; 
$action = 'view';
$class = new $request(); // Creates an blog object
$class->$action(); // Runs the blog function view

Sınıfları başlatmasını için gösterim kullanılarak önceden her sınıf / metodu kabul parametrelerini bilmesini gerektirir. Yani bir factory pattern onunla keyfi parametreleri kabul edeceğini tasarım olamaz.

Call_user_func_array () kullanarak keyfi parametreleri kullanmak için izin verir.

$request = 'blog'; 
$action = 'view';
$params = array(
   $_GET['category'],
   $_GET['limit']
);
call_user_func_array(array($request, $action), $params);

Yani yukarıdaki kodu değişmez eşdeğerdir:

blog::view($_GET['category'], $_GET['limit']);

Temelde, call_user_func_array () yöntemi, blog parametre olarak onun içinde her değeri geçen, array $ params düzleştiren :: görünümü ().

Dinamik / object yöntem çağrısı ile aynı yapmak için:

call_user_func_array(array(new $request, $action), $params);

Ancak, bu keyfi bir sınıfın bir örneğini oluşturarak, ve bu parametrelerin keyfi bir sayı ile geçen sorunu çözmüyor. Bunu yapmak için ReflectionClass kullanabilirsiniz.

Örnek:

$request = 'blog';
$action = 'view';
$configs = array('something', 'something else');
$params = array(
   $_GET['category'],
   $_GET['limit']
);
$instance = call_user_func_array(
   array(new ReflectionClass($request), 'newInstance'), 
   $configs
);
$return = call_user_func_array(array($instance, $action), $params);

Bu eşdeğer olacaktır:

$configs = array('something', 'something else');
$params = array(
   $_GET['category'],
   $_GET['limit']
);
$blog = new blog($configs[0], $configs[1]);
$blog->view($_GET['category'], $_GET['limit']);

Bu araçları ile dinamik keyfi Nesneler örneğini ve onların __ constructor () yanı sıra herhangi bir yönteme parametre keyfi sayıda geçmektedir.

If you meant best in terms of functionality, use call_user_func_array() and ReflectionClass(). If you meant best in terms of performance, don't worry about it. Good design and functionality improves performance more.

Ben de seni anlıyorum emin değilim, ama factory design pattern kullanabilirsiniz.

Sorunuzu doğru anlamak, sonra ben bunun için eval kullanmak istiyorsunuz. Ayrıca statik fonksiyonlar için bunu yapabilirsiniz. Örneğin, burada ben bir kaç yıl önce inşa edilmiş bir siteden bazı kodudur.

function StaticObjectPrint($mysql,$template, $objecttype, $debug=0) {
    foreach(eval("return $objecttype::ReturnStaticVariablesForPrinting(\$mysql);") as $key => $value) {
        global $$key;
        $$key = $value;
    }
    if($debug==1)
        print_r ($GLOBALS);

    return ParsePlainTextFile($template,1);
}

Bu durumda, orada nesneleri birkaç farklı sınıflar vardı, ama hepsi bir ReturnStaticVariablesForPrinting işlevi vardı. Bir kullanıcı tıklanan nesnenin hangi türüne bağlı olarak, her bir nesne örneğini kalmadan, o nesne hakkında bazı statik bilgiler döndürür (ve hafıza bir demet kadar kravat) olacaktır. Bu nesne özelliklerinin listelerini üretmek için yararlı oldu. (Bu bazı OO ilkelerini ihlal farkında, ama bu hız için gerekli)