• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • mysqli::ping()

    (PHP 5, PHP 7)

    ping 一个连接,或者如果连接处于断开状态,重新连接

    说明

    面向对象风格
    mysqli::ping(void): bool
    过程化风格
    mysqli_ping(mysqli$link): bool

    检查到服务器的连接是否还正常。在启用mysqli.reconnect选项的前提下,如果连接已经断开, ping 操作会尝试重新建立连接。

    Note: mysqlnd 驱动会忽略php.ini中的 mysqli.reconnect 选项,所以它不会自动重连。

    客户端建立连接之后,长时间处于闲置状态,可以用此函数来检查服务器是否关闭了这个连接,如有必要,将会自动重新建立到服务器的连接。

    参数

    $link

    仅以过程化样式:由mysqli_connect()或mysqli_init()返回的链接标识。

    返回值

    成功时返回TRUE,或者在失败时返回FALSE

    范例

    Example #1 mysqli::ping()例程

    面向对象风格

    <?php
    $mysqli = new mysqli("localhost", "my_user", "my_password", "world");
    /* 检查连接 */
    if ($mysqli->connect_errno) {
        printf("Connect failed: %s\n", $mysqli->connect_error);
        exit();
    }
    /* 检查连接是否还活跃 */
    if ($mysqli->ping()) {
        printf ("Our connection is ok!\n");
    } else {
        printf ("Error: %s\n", $mysqli->error);
    }
    /* 关闭连接 */
    $mysqli->close();
    ?>
    

    过程化风格

    <?php
    $link = mysqli_connect("localhost", "my_user", "my_password", "world");
    /* 检查连接 */
    if (mysqli_connect_errno()) {
        printf("Connect failed: %s\n", mysqli_connect_error());
        exit();
    }
    /* 检查连接是否还活跃 */
    if (mysqli_ping($link)) {
        printf ("Our connection is ok!\n");
    } else {
        printf ("Error: %s\n", mysqli_error($link));
    }
    /* 关闭连接 */
    mysqli_close($link);
    ?>
    

    以上例程会输出:

    Our connection is ok!
    
    This does not work with mysqlnd and is marked as wontfix: https://bugs.php.net/bug.php?id=52561
    As jay at grooveshark dot com very helpfully pointed out, the mysqlnd driver which is becoming pretty standard does not obey reconnect commands. If you have a DB wrapper class (which hopefully you do) you can implement your own version of ping() such as:
    <?php
    class db extends mysqli
    {
      private $db_host;
      private $db_user;
      private $db_pass;
      private $db_name;
      private $persistent;
      public function __construct($db_host, $db_user, $db_pass, $db_name, $persistent = true)
      {
        $this->db_host = $db_host;
        $this->db_user = $db_user;
        $this->db_pass = $db_pass;
        $this->db_name = $db_name;
        $this->persistent = $persistent;
        parent::init();
        parent::options(MYSQLI_OPT_CONNECT_TIMEOUT, 1);
        @parent::real_connect(($this->persistent ? 'p:' : '') . $this->db_host, $this->db_user, $this->db_pass, $this->db_name);
        if ($this->connect_errno)
          die("All DB servers down!\n");
      }
      public function ping()
      {
        @parent::query('SELECT LAST_INSERT_ID()');
        if ($this->errno == 2006)
          $this->__construct($this->db_host, $this->db_user, $this->db_pass, $this->db_name, $this->persistent);
      }
    ...
    }
    $db = new db(DB_HOST, DB_USER, DB_PASS, DB_NAME);
    // Some code that potentially takes a really long time to execute goes here
    // Ping for safety to try to gracefully reconnect
    $db->ping();
    // Now we should be able to run queries again
    $db->query('SELECT LAST_INSERT_ID()');
    ?>
    If you wanted you could even put "$this->ping();" at the top of db::query() to avoid any explicit reconnection calls but I wouldn't recommend it due to the (slight) overhead of running the cheap "SELECT LAST_INSERT_ID()" query every time prior to running your real intended query. There are probably even cheaper queries to run in favor of "SELECT LAST_INSERT_ID()" but it was the first that came to mind and is cheap enough for most purposes since you shouldn't be calling ping() a whole bunch anyway.
    The behaviour about the option mysqli.reconnect is default set to Off at Debian PHP Packages. So i would recommend to update the first line description about the recommendation at the option mysqli.reconnect. (practice note ;))

    上篇:mysqli::options()

    下篇:mysqli::poll()