简体   繁体   中英

Fatal error: Cannot redeclare class Net_SSH2 in /var/www/phpseclib/Net/SSH2.php on line 194

I have created a CI model that dynamically loads certain classes depending on a parameter that is passed in. These classes are just wrapper classes around phpseclib to make ssh connections to different devices. What I'm noticing is that when I try to execute one particular method, I'm getting the above error message.

Here's some sample code to help you understand what I'm doing. This is what my model looks like:

    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;
         }
               }

As you can see, i'm dynamically determining which class to load depending on the switchname that is passed in. This code successfully loads a class called "device123.php", let's say. Class device123 in turn, instantiates the SSH2 object that comes with the phpseclib, and uses it to send ssh commands to the device.

Here's a clip of code from device 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;
}

I don't think I quite understand how I can be redeclaring the SSH2 class... but i wanted to see if perhaps I was not destroying / cleaning up after myself properly. To help troubleshoot, I've tried adding debug echo statements in the constructor and destructor of both the SSH2 class, and also the wrapper class called device123. It all looks proper...

I don't think I'm on the right track... Can you tell me where you think I should start looking? Is it because it's possible that both methods are called ... one after the other... and both can possibly load the same class?

Thanks.

当您尝试多次加载类时,例如在其他源文件中存在相同的名称类,PHP会给出此类错误。

All php classes must have unique names. You should include all the files at one place, keep track of all loaded classes if you want a lazy loading, or just use http://cz.php.net/include_once . The same goes for the require function.

The _once postfix does exactly what you need: it prevents the files from loading if it already has been loaded, thus preventing the class redeclaration.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM