1

渡されるパラメーターに応じて特定のクラスを動的にロードするCIモデルを作成しました。これらのクラスは、さまざまなデバイスへのssh接続を行うためのphpseclibのラッパークラスです。私が気付いているのは、特定のメソッドを実行しようとすると、上記のエラーメッセージが表示されることです。

これが私がしていることを理解するのに役立つサンプルコードです。これは私のモデルがどのように見えるかです:

    public function get_portstatusall($ip, $switchname)
    {           
        $classname = $this->switchToClassName($switchname);
        try{
        include_once(APPPATH.'libraries/'.$classname.'.php');                 
        $switch_obj = new $classname($ip, 'password', '');
        $switch_obj->connect();
        $data = $switch_obj->dosomething(); 
        $switch_obj->disconnect();  
        return $data;
        }
         catch (Exception $e) {
            echo 'this really should be logged...';
            return false;
         }
    }   

            public function get_portstatusindividual($ip, $switchname)
            {           
                 $classname = $this->switchToClassName($switchname);
                 try{

                     include_once(APPPATH.'libraries/'.$classname.'.php'); 
         $switch_obj = new $classname($ip, 'password', '');
         $switch_obj->connect();
         $data = $switch_obj->dosomethingelse();    
         $switch_obj->disconnect();  
         return $data;
         }
         catch (Exception $e) {
            echo 'this really should be logged...';
            return false;
         }
               }

ご覧のとおり、渡されたスイッチ名に応じて、ロードするクラスを動的に決定しています。このコードは、「device123.php」というクラスを正常にロードします。次に、クラスdevice123は、phpseclibに付属するSSH2オブジェクトをインスタンス化し、それを使用してsshコマンドをデバイスに送信します。

これがデバイス123からのコードのクリップです:

class device123
{
// sample code to demo how to use phpseclib to create an interactive ssh session.
//this library relies on phpseclib.  you must include this class and SSH2.php from Net/phpseclib.


private $_hostname;
private $_password;
private $_username;
private $_connection;
private $_data;
private $_timeout;
private $_prompt;

public function __construct($hostname, $password, $username = "", $timeout = 10) 
//public function __construct($params) 
{
    echo 'in the switch constructor<br>';
    set_include_path(get_include_path() . PATH_SEPARATOR . '/var/www/phpseclib');
    include('Net/SSH2.php');

   $this->_hostname = $hostname;
    $this->_password = $password;
    $this->_username = $username;

} // __construct

public function connect() 
{
    $ssh = new Net_SSH2($this->_hostname); 
    if (!$ssh->login($this->_username, $this->_password)) { //if you can't log on...
    die("Error: Authentication Failed for $this->_hostname\n");
    }
    else  {

    $output= $ssh->write("\n"); //press any key to continue prompt;
    $prompt=$ssh->read('/([0-9A-Z\-])*(#)(\s*)/i', NET_SSH2_READ_REGEX); 
    if (!$prompt) {
        die("Error: Problem connecting for $this->_hostname\n");
    }  
    else {

        $this->_connection = $ssh;
    }

    }
} // connect


public function close() 
{
    $this->_send('exit');
} // close

public function disconnect()
{
  $this->_connection->disconnect();
  $ssh=NULL;
}

SSH2クラスを再宣言する方法がよくわからないと思いますが、自分の後で適切に破棄/クリーンアップしていないかどうかを確認したかったのです。トラブルシューティングに役立てるために、SSH2クラスとdevice123というラッパークラスの両方のコンストラクタとデストラクタにデバッグエコーステートメントを追加してみました。それはすべて適切に見えます...

私は正しい方向に進んでいないと思います...私がどこから探し始めるべきだと思うか教えていただけますか?両方のメソッドが次々に呼び出され、両方が同じクラスをロードできる可能性があるためですか?

ありがとう。

4

2 に答える 2

0

同じ名前のクラスが他のソースファイルに存在するように、クラスを複数回ロードしようとすると、Phpはそのようなエラーを出します。

于 2012-09-01T09:37:24.267 に答える
0

すべてのphpクラスには一意の名前が必要です。すべてのファイルを1か所にまとめるか、遅延読み込みが必要includeな場合は読み込まれたすべてのクラスを追跡するか、http://cz.php.net/include_onceを使用する必要があります。同じことがrequire関数にも当てはまります。

接尾辞は、_once必要なことを正確に実行します。ファイルがすでにロードされている場合はファイルがロードされないため、クラスの再宣言が防止されます。

于 2012-09-03T12:33:14.013 に答える