【问题标题】:PHP/Codeigniter FTP TimeoutPHP/Codeigniter FTP 超时
【发布时间】:2010-06-12 13:53:28
【问题描述】:

我正在尝试使用 Codeigniter 的 FTP 库从我的 PHP 脚本访问 FTP 服务器。这些功能很好用,但是在测试脚本时,我发现如果我尝试连接到不存在的服务器,脚本不会终止并显示任何类型的错误消息。

页面继续执行,直到网络服务器放弃,返回一个空文档。

所以我想知道,有没有办法限制 Codeigniter 可以尝试连接到 FTP 服务器的时间,然后在超时时显示一条消息?

我尝试使用 php 函数 set_time_limit(),但它的行为并不符合我的预期。

感谢您的帮助。

【问题讨论】:

    标签: php codeigniter ftp execution


    【解决方案1】:

    Codeigniter 的 ftp 类使用支持第三个可选参数 timeout (http://ca2.php.net/manual/en/function.ftp-connect.php) 的底层 ftp_connect php 调用。

    Codeigniter 但是不使用它,但允许扩展它提供的默认库(前提是您愿意做一些工作并检查您对核心所做的任何更新都不会破坏扩展类的功能) .因此,要解决您的问题,您可以在应用程序库文件夹中创建一个新库:

    <?php
    
    class MY_FTP extends CI_FTP { //Assuming that in your config.php file, your subclass prefix is set to 'MY_' like so: $config['subclass_prefix'] = 'MY_';
    
        var $timeout = 90;
        /**
         * FTP Connect
         *
         * @access  public
         * @param   array    the connection values
         * @return  bool
         */
        function connect($config = array())
        {
            if (count($config) > 0)
            {
                $this->initialize($config);
            }
    
            if (FALSE === ($this->conn_id = ftp_connect($this->hostname, $this->port, $this->timeout)))
            {
                if ($this->debug == TRUE)
                {
                    $this->_error('ftp_unable_to_connect');
                }
                return FALSE;
            }
    
            if ( ! $this->_login())
            {
                if ($this->debug == TRUE)
                {
                    $this->_error('ftp_unable_to_login');
                }
                return FALSE;
            }
    
            // Set passive mode if needed
            if ($this->passive == TRUE)
            {
                ftp_pasv($this->conn_id, TRUE);
            }
    
            return TRUE;
        }
    }
    ?>
    

    从您的脚本中,您可以将超时选项添加到您的配置数组中:

    $this->load->library('ftp'); //if ftp is not autoloaded
    $ftp_params = array('hostname'=>'1.2.3.4', 'port'=>21, 'timeout'=>10); //timout is 10 seconds instead of default 90
    $ftp_conn = $this->ftp->connect($ftp_params);
    if(FALSE === $ftp_conn) {
    //Code to handle error
    }
    

    ftp 类并非设计用于提供错误消息,除非在 te config 数组中将 debug 参数设置为 TRUE,在这种情况下它只会显示错误。但是它也可以被覆盖,因为所有错误都会调用类中的函数 _error()。因此,您可以在 $ftp_params 数组中设置 'debug' => true,然后在 MY_ftp 中添加一个函数,如下所示:

    /**
     * This function overrides 
     */
    function _error($line)
    {
        $this->error = $line;
    }
    

    然后有一个函数getError() /** * 这个函数覆盖 */ 函数 get_error() { 返回 $this-> 错误; }

    如果

    $ftp_conn = $this->ftp->connect($ftp_params);
    

    返回false,可以调用

    $error = $this->ftp->get_error();
    

    获取您的错误并显示它。 现在,您始终可以通过进一步自定义类来自定义并拥有更复杂的错误处理机制...

    希望它能回答你的问题。

    【讨论】:

    • 哇!谢谢莫里斯!那工作得很好。这实际上非常简单。为什么 CI 在默认情况下不使用该选项? strage....非常感谢您的帮助:D
    【解决方案2】:

    答案很简单,不要尝试连接不存在的服务器

    【讨论】:

    • 嗯,是的,这很明智,但是我根本没有办法捕获这个错误吗?在我尝试连接之前检查服务器是否存在的方法怎么样?
    • -1 在一个完美的世界中,程序员可以假设可以信任用户输入正确的信息。但是……这永远不会发生。永远做好最坏的打算。
    • 我不知道,也许是ping 吧?有一些创造性的方法可以解决这个问题。我不是信任用户,我说的是在尝试连接之前验证
    • 验证对我的应用程序来说是最重要的事情。在尝试 FTP 连接之前,我确实找到了一个很好的小脚本来 ping 服务器,但是如果服务器实际上已经启动,它会增加额外的几秒钟的执行时间,这并不是真正必要的。 Maurice 提供的解决方案效果很好。图书馆的一个不错的小扩展。奇怪的是 CI 怎么不使用内置 php ftp 函数的那个​​额外参数!谢谢你们的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    • 2015-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-07
    • 2013-02-15
    相关资源
    最近更新 更多