PHP 5 Yöntem durdurma. *

2 Cevap php

Ben PHP için bir Log sistemi uygulayan, ve ben biraz şaşırıp.

Tüm yapılandırma XML dosyasında tanımlanır, her yöntemi yapmalısınız bildirir. XML iyi çözümlenir ve çok boyutlu bir dizi dönüştürülür (classname => array of methods). Şimdiye kadar, çok iyi.

Basit bir örnek verelim:

#A.php
class A {
    public function foo($bar) {
        echo ' // Hello there !';
    }

public function bar($foo) {
    echo " $ù$ùmezf$z !";
}
}

#B.php
class B {
public function far($boo) {
    echo $boo;  
}
}

Şimdi, ben bu yapılandırma dosyası var diyelim:

<interceptor>
<methods class="__CLASS_DIR__A.php">
        <method name="foo">
    <log-level>INFO</log-level>
    <log-message>Transaction init</log-message>
        </method>
</methods>  
<methods class="__CLASS_DIR__B.php">
        <method name="far">
    <log-level>DEBUG</log-level>
    <log-message>Useless</log-message>
        </method>
</methods>
</interceptor>

İsterdim şey AT RUNTIME ONLY (XML ayrıştırıcı işini yapmış kez) olduğunu:

#Logger.php (its definitely NOT a final version) -- generated by the XML parser
class Logger {
public function __call($name,$args) {
    $log_level = args[0];
    $args = array_slice($args,1);
    switch($method_name) {
        case 'foo':
        case 'far':
        //case .....
            //write in log files
            break;

    }
    //THEN, RELAY THE CALL TO THE INITIAL METHOD
 }
}

    #"dynamic" A.php
class A extends Logger {
    public function foo($log_level, $bar) {
    parent::foo($log_level, $bar);
        echo ' // Hello there !';
    }

public function bar($foo) {
    echo " $ù$ùmezf$z !";
}
}

#"dynamic" B.php
class B extends Logger {
public function far($log_level, $boo) {
    parent::far($log_level, $bar);
    echo $boo;  
}
}

Burada büyük bir sorundur XML çözümleyici, işini tamamlandıktan sonra, onların "dinamik" sürümleri içine A ve B dönüştürmektir.

Ya da en azından program bittikten sonra tekrar kendi orijinal sürümlerine gelmek için bir yol bulmak - İdeal (I dosyalarında, ortalama) hiç A kodu ve B değiştirmeden başarmak olacaktır.

Açık olmak gerekirse, ben PHP yöntem çağrıları önünü en uygun yolu bulmak istiyorum.

Bu konuda fikirleriniz nelerdir?

PS: ve tabii ki, (hiçbir durdurma etkinse farklı ya da değil) müşteri kodu YOK SONUÇ olmalıdır.

2 Cevap

Sen eval() aslında sınıfları tanımlamak için kullanabilirsiniz, ancak gerekir be very careful. eval() function çok tehlikeli olabilir.

Böyle bir şey:

$parentName = 'Bar';

eval('class Foo extends ' . $parentName . ' { }');

http://php.net/eval

Bu çözüm bir kez daha eval kullanır, ama ben dinamik miras gerçekten güzel bir yol olduğunu düşünüyorum çünkü ben zaten senin göz için göndeririz.

Burada yöntemi (farklı bir sınıf da varsayılan uzanan bu durumda) değiştirilebilir bazı varsayılan sınıfını genişleten bir aracı sınıfının kullanılmasıdır.

Ben bu çalışma için bu tür izin vermiyor senin kurulumunda ne gibi belirsiz kulüpler - Bunu açıklamak ben belki iyi bir tavsiye verebilir.

<?php

/*
 * One of the following classes will be the superclass of the Child
 */

class Ancestor {
    function speak() {
        echo 'Ancestor <br />';
    }
}

class Mum extends Ancestor {
    function speak() {
        parent::speak();
        echo 'Mum <br />';
    }
}

class Dad extends Ancestor {
    function speak() {
        parent::speak();
        echo 'Dad <br />';
    }
}

/*
 * Decide on which class we wish to make the superclass of our Child
 */

$parentClass = null;

if (isset($_GET['parent'])) {
    $parentClass = $_GET['parent'];
    if (!class_exists($parentClass)) {
        $parentClass = "Ancestor";
    }
}

if (!is_null($parentClass)) {
    eval("class ChildParent extends $parentClass {};");
} else {
    class ChildParent extends Ancestor {};
}

if (class_exists('ChildParent')) {
class Child extends ChildParent
{
    function speak() {
        parent::speak();
        echo 'Child <br />';
    }
}
}

/*
 * Show what's going on
 */

echo '<a href="?">Either</a> | <a href="?parent=Mum">Mum</a> | <a href="?parent=Dad">Dad</a> <br />';

$child = new Child();
$child->speak();*