Set/mysqlinfo-Phpdoc专题

MySQL Drivers and Plugins

目录

PHP offers several MySQL drivers and plugins for accessing and handling MySQL.

The differences and functionality of the MySQL extensions are described within the overview of this section.

Overview of the MySQL PHP drivers

目录

Introduction

目录

Depending on the version of PHP, there are either two or three PHP APIs for accessing the MySQL database. PHP 5 users can choose between the deprecated mysql extension, mysqli, or PDO_MySQL. PHP 7 removes the mysql extension, leaving only the latter two options.

This guide explains the terminology used to describe each API, information about choosing which API to use, and also information to help choose which MySQL library to use with the API.

Terminology overview

This section provides an introduction to the options available to you when developing a PHP application that needs to interact with a MySQL database.

What is an API?

An Application Programming Interface, or API, defines the classes, methods, functions and variables that your application will need to call in order to carry out its desired task. In the case of PHP applications that need to communicate with databases the necessary APIs are usually exposed via PHP extensions.

APIs can be procedural or object-oriented. With a procedural API you call functions to carry out tasks, with the object-oriented API you instantiate classes and then call methods on the resulting objects. Of the two the latter is usually the preferred interface, as it is more modern and leads to better organized code.

When writing PHP applications that need to connect to the MySQL server there are several API options available. This document discusses what is available and how to select the best solution for your application.

What is a Connector?

In the MySQL documentation, the term connector refers to a piece of software that allows your application to connect to the MySQL database server. MySQL provides connectors for a variety of languages, including PHP.

If your PHP application needs to communicate with a database server you will need to write PHP code to perform such activities as connecting to the database server, querying the database and other database-related functions. Software is required to provide the API that your PHP application will use, and also handle the communication between your application and the database server, possibly using other intermediate libraries where necessary. This software is known generically as a connector, as it allows your application to connect to a database server.

What is a Driver?

A driver is a piece of software designed to communicate with a specific type of database server. The driver may also call a library, such as the MySQL Client Library or the MySQL Native Driver. These libraries implement the low-level protocol used to communicate with the MySQL database server.

By way of an example, the PHP Data Objects (PDO) database abstraction layer may use one of several database-specific drivers. One of the drivers it has available is the PDO MYSQL driver, which allows it to interface with the MySQL server.

Sometimes people use the terms connector and driver interchangeably, this can be confusing. In the MySQL-related documentation the term “driver” is reserved for software that provides the database-specific part of a connector package.

What is an Extension?

In the PHP documentation you will come across another term - extension. The PHP code consists of a core, with optional extensions to the core functionality. PHP's MySQL-related extensions, such as the mysqli extension, and the mysql extension, are implemented using the PHP extension framework.

An extension typically exposes an API to the PHP programmer, to allow its facilities to be used programmatically. However, some extensions which use the PHP extension framework do not expose an API to the PHP programmer.

The PDO MySQL driver extension, for example, does not expose an API to the PHP programmer, but provides an interface to the PDO layer above it.

The terms API and extension should not be taken to mean the same thing, as an extension may not necessarily expose an API to the programmer.

Choosing an API

PHP offers three different APIs to connect to MySQL. Below we show the APIs provided by the mysql, mysqli, and PDO extensions. Each code snippet creates a connection to a MySQL server running on "example.com" using the username "user" and the password "password". And a query is run to greet the user.

示例 #1 Comparing the three MySQL APIs

<?php
// mysqli
$mysqli = new mysqli("example.com", "user", "password", "database");
$result = $mysqli->query("SELECT 'Hello, dear MySQL user!' AS _message FROM DUAL");
$row = $result->fetch_assoc();
echo htmlentities($row['_message']);

// PDO
$pdo = new PDO('mysql:host=example.com;dbname=database', 'user', 'password');
$statement = $pdo->query("SELECT 'Hello, dear MySQL user!' AS _message FROM DUAL");
$row = $statement->fetch(PDO::FETCH_ASSOC);
echo htmlentities($row['_message']);

// mysql
$c = mysql_connect("example.com", "user", "password");
mysql_select_db("database");
$result = mysql_query("SELECT 'Hello, dear MySQL user!' AS _message FROM DUAL");
$row = mysql_fetch_assoc($result);
echo htmlentities($row['_message']);
?>

Recommended API

It is recommended to use either the mysqli or PDO_MySQL extensions. It is not recommended to use the old mysql extension for new development, as it was deprecated in PHP 5.5.0 and was removed in PHP 7. A detailed feature comparison matrix is provided below. The overall performance of all three extensions is considered to be about the same. Although the performance of the extension contributes only a fraction of the total run time of a PHP web request. Often, the impact is as low as 0.1%.

Feature comparison

  ext/mysqli PDO_MySQL ext/mysql
PHP version introduced 5.0 5.1 2.0
Included with PHP 5.x Yes Yes Yes
Included with PHP 7.x Yes Yes No
Development status Active Active Maintenance only in 5.x; removed in 7.x
Lifecycle Active Active Deprecated in 5.x; removed in 7.x
Recommended for new projects Yes Yes No
OOP Interface Yes Yes No
Procedural Interface Yes No Yes
API supports non-blocking, asynchronous queries with mysqlnd Yes No No
Persistent Connections Yes Yes Yes
API supports Charsets Yes Yes Yes
API supports server-side Prepared Statements Yes Yes No
API supports client-side Prepared Statements No Yes No
API supports Stored Procedures Yes Yes No
API supports Multiple Statements Yes Most No
API supports Transactions Yes Yes No
Transactions can be controlled with SQL Yes Yes Yes
Supports all MySQL 5.1+ functionality Yes Most No

Choosing a library

The mysqli, PDO_MySQL and mysql PHP extensions are lightweight wrappers on top of a C client library. The extensions can either use the mysqlnd library or the libmysqlclient library. Choosing a library is a compile time decision.

The mysqlnd library is part of the PHP distribution since 5.3.0. It offers features like lazy connections and query caching, features that are not available with libmysqlclient, so using the built-in mysqlnd library is highly recommended. See the mysqlnd documentation for additional details, and a listing of features and functionality that it offers.

示例 #1 Configure commands for using mysqlnd or libmysqlclient

// Recommended, compiles with mysqlnd
$ ./configure --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-mysql=mysqlnd

// Alternatively recommended, compiles with mysqlnd as of PHP 5.4
$ ./configure --with-mysqli --with-pdo-mysql --with-mysql

// Not recommended, compiles with libmysqlclient
$ ./configure --with-mysqli=/path/to/mysql_config --with-pdo-mysql=/path/to/mysql_config --with-mysql=/path/to/mysql_config

Library feature comparison

It is recommended to use the mysqlnd library instead of the MySQL Client Server library (libmysqlclient). Both libraries are supported and constantly being improved.

  MySQL native driver (mysqlnd) MySQL client server library (libmysqlclient)
Part of the PHP distribution Yes No
PHP version introduced 5.3.0 N/A
License PHP License 3.01 Dual-License
Development status Active Active
Lifecycle No end announced No end announced
PHP 5.4 and above; compile default (for all MySQL extensions) Yes No
PHP 5.3; compile default (for all MySQL extensions) No Yes
Compression protocol support Yes (5.3.1+) Yes
SSL support Yes (5.3.3+) Yes
Named pipe support Yes (5.3.4+) Yes
Non-blocking, asynchronous queries Yes No
Performance statistics Yes No
LOAD LOCAL INFILE respects the open_basedir directive Yes No
Uses PHP's native memory management system (e.g., follows PHP memory limits) Yes No
Return numeric column as double (COM_QUERY) Yes No
Return numeric column as string (COM_QUERY) Yes Yes
Plugin API Yes Limited
Read/Write splitting for MySQL Replication Yes, with plugin No
Load Balancing Yes, with plugin No
Fail over Yes, with plugin No
Lazy connections Yes, with plugin No
Query caching Yes, with plugin No
Transparent query manipulations (E.g., auto-EXPLAIN or monitoring) Yes, with plugin No
Automatic reconnect No Optional

Concepts

目录

These concepts are specific to the MySQL drivers for PHP.

Buffered and Unbuffered queries

Queries are using the buffered mode by default. This means that query results are immediately transferred from the MySQL Server to PHP and then are kept in the memory of the PHP process. This allows additional operations like counting the number of rows, and moving (seeking) the current result pointer. It also allows issuing further queries on the same connection while working on the result set. The downside of the buffered mode is that larger result sets might require quite a lot memory. The memory will be kept occupied till all references to the result set are unset or the result set was explicitly freed, which will automatically happen during request end the latest. The terminology "store result" is also used for buffered mode, as the whole result set is stored at once.

Note:

When using libmysqlclient as library PHP's memory limit won't count the memory used for result sets unless the data is fetched into PHP variables. With mysqlnd the memory accounted for will include the full result set.

Unbuffered MySQL queries execute the query and then return a <span class="type">resource while the data is still waiting on the MySQL server for being fetched. This uses less memory on the PHP-side, but can increase the load on the server. Unless the full result set was fetched from the server no further queries can be sent over the same connection. Unbuffered queries can also be referred to as "use result".

Following these characteristics buffered queries should be used in cases where you expect only a limited result set or need to know the amount of returned rows before reading all rows. Unbuffered mode should be used when you expect larger results.

Because buffered queries are the default, the examples below will demonstrate how to execute unbuffered queries with each API.

示例 #1 Unbuffered query example: mysqli

<?php
$mysqli  = new mysqli("localhost", "my_user", "my_password", "world");
$uresult = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT);

if ($uresult) {
   while ($row = $uresult->fetch_assoc()) {
       echo $row['Name'] . PHP_EOL;
   }
}
$uresult->close();
?>

示例 #2 Unbuffered query example: pdo_mysql

<?php
$pdo = new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_pass');
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);

$uresult = $pdo->query("SELECT Name FROM City");
if ($uresult) {
   while ($row = $uresult->fetch(PDO::FETCH_ASSOC)) {
       echo $row['Name'] . PHP_EOL;
   }
}
?>

示例 #3 Unbuffered query example: mysql

<?php
$conn = mysql_connect("localhost", "my_user", "my_pass");
$db   = mysql_select_db("world");

$uresult = mysql_unbuffered_query("SELECT Name FROM City");
if ($uresult) {
   while ($row = mysql_fetch_assoc($uresult)) {
       echo $row['Name'] . PHP_EOL;
   }
}
?>

Character sets

Ideally a proper character set will be set at the server level, and doing this is described within the » Character Set Configuration section of the MySQL Server manual. Alternatively, each MySQL API offers a method to set the character set at runtime.

Caution

The character set should be understood and defined, as it has an affect on every action, and includes security implications. For example, the escaping mechanism (e.g., <span class="function">mysqli_real_escape_string for mysqli, <span class="function">mysql_real_escape_string for mysql, and <span class="methodname">PDO::quote for PDO_MySQL) will adhere to this setting. It is important to realize that these functions will not use the character set that is defined with a query, so for example the following will not have an effect on them:

示例 #1 Problems with setting the character set with SQL

<?php

$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

// Will NOT affect $mysqli->real_escape_string();
$mysqli->query("SET NAMES utf8mb4");

// Will NOT affect $mysqli->real_escape_string();
$mysqli->query("SET CHARACTER SET utf8mb4");

// But, this will affect $mysqli->real_escape_string();
$mysqli->set_charset('utf8mb4');

// But, this will NOT affect it (UTF-8 vs utf8mb4) -- don't use dashes here
$mysqli->set_charset('UTF-8');

?>

Below are examples that demonstrate how to properly alter the character set at runtime using each API.

Note: Possible UTF-8 confusion

Because character set names in MySQL do not contain dashes, the string "utf8" is valid in MySQL to set the character set to UTF-8 (up to 3 byte UTF-8 Unicode Encoding). The string "UTF-8" is not valid, as using "UTF-8" will fail to change the character set and will throw an error.

示例 #2 Setting the character set example: mysqli

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

printf("Initial character set: %s\n", $mysqli->character_set_name());

if (!$mysqli->set_charset('utf8mb4')) {
    printf("Error loading character set utf8mb4: %s\n", $mysqli->error);
    exit;
}

echo "New character set information:\n";
print_r( $mysqli->get_charset() );

?>

示例 #3 Setting the character set example: pdo_mysql

Note: This only works as of PHP 5.3.6.

<?php
$pdo = new PDO("mysql:host=localhost;dbname=world;charset=utf8mb4", 'my_user', 'my_pass');
?>

示例 #4 Setting the character set example: mysql

<?php
$conn = mysql_connect("localhost", "my_user", "my_pass");
$db   = mysql_select_db("world");

echo 'Initial character set: ' .  mysql_client_encoding($conn) . "\n";

if (!mysql_set_charset('utf8mb4', $conn)) {
    echo "Error: Unable to set the character set.\n";
    exit;
}

echo 'Your current character set is: ' .  mysql_client_encoding($conn);
?>

MySQL增强版扩展

目录

mysqli扩展允许我们访问MySQL 4.1及以上版本提供的功能。关于MySQL数据库 服务端的信息请参阅» http://www.mysql.com/

是在PHP中可以用于MySQL访问的软件的一个概览。

Mysql的文档请查看» http://dev.mysql.com/doc/

本文档中部分内容经过Oracle公司授权引自MySQL手册。 Parts of this documentation included from MySQL manual with permissions of Oracle Corporation.

示例

所有mysqli文档示例使用的都是world数据库,该数据库可以从» http://dev.mysql.com/doc/world-setup/en/index.html下载。

Overview

这一部分对在PHP应用开发过程中需要和Mysql数据库交互时可用的选择进行一个简单介绍。

什么是API?

一个应用程序接口(Application Programming Interface的缩写),定义了类,方法,函数,变量等等一切 你的应用程序中为了完成特定任务而需要调用的内容。在PHP应用程序需要和数据库进行交互的时候所需要的API 通常是通过PHP扩展暴露出来(给终端PHP程序员调用)。

API可以是面向过程的,也可以是面向对象的。对于面向过程的API,我们通过调用函数来完成任务,而对于面向对象的API, 我们实例化类,并在实例化后得到的对象上调用方法。对于这两种接口而言,后者通常是首选的,因为它更加现代化,并且 给我们带来了良好的代码结构。

当构建一个需要连接到MySQL服务端的PHP应用的时候,有好几种API可供选择。此文档就是讨论这些可用的API并讨论如何为 你的应用选择一个最佳的解决方案。

什么是连接器?

在MySQL文档中,术语connector解释为“一段允许你的应用连接到MySQL数据库服务器的软件代码”。 MySQL提供了很多语言的连接器,其中包括PHP的。

在你的PHP应用需要和一个数据库服务器交互的时候,你需要书写PHP代码去完成“连接数据库服务器”,“查询数据库“以及其他数据库相关功能 等一系列活动。你的PHP应用将会使用提供这些API的软件,或者在需要的时候使用一些中间库,来处理你的应用和数据库服务器之间的交互。 这种软件通常被认为是连接器,它允许你的引用连接到数据库服务器。

什么是驱动?

驱动是一段设计用来于一种特定类型的数据库服务器进行交互的软件代码。驱动可能会调用一些库,比如MySQL客户端库或者MySQL Native驱动库。 这些库实现了用于和MySQL数据库服务器进行交互的底层协议。

通过一个例子PDO(PHP Database Object的缩写)数据库抽象层可以 使用多种特定数据库的驱动。其中一种驱动就是PDO MYSQL驱动,它就是与MySQL服务器之间的接口。

有时大家会不加区分的使用连接器和驱动这两个术语。在MySQL相关文档中“driver”术语被作为一个连接器包 中提供特定数据库部分的软件代码。

什么是扩展?

在PHP文档中你还会发现很多其他的扩展。PHP代码是由一个核心,一些可选扩展组成了核心功能。PHP 的MySQL相关扩展,比如mysqlimysql都是基于PHP扩展框架实现的。

扩展一个典型的作用就是暴露一个API给PHP程序员,允许扩展自己的功能可以被程序员使用。当然,也有一部分基于PHP扩展框架 开发的扩展不会给PHP程序员暴露API接口。

比如说PDO MySQL驱动扩展,就没有向PHP程序员暴露API接口,但是向它上层的PDO层提供了一个接口。

术语API和扩展描述的不是同一类事物,因为扩展可能并不需要暴露一个API接口给程序员。

PHP中提供的用于MySQL的主要API是什么?

当考虑连接到MySQL数据库服务器的时候,有三种主要的API可供选择:

  • PHP的MySQL扩展

  • PHP的mysqli扩展

  • PHP数据对象(PDO)

三者都有各自的优缺点。下面的讨论就是为了对每种API的关键方面给出一个简短的介绍。

什么是PHP的MySQL扩展?

这是设计开发允许PHP应用与MySQL数据库交互的早期扩展。mysql扩展提供了一个面向过程 的接口,并且是针对MySQL4.1.3或更早版本设计的。因此,这个扩展虽然可以与MySQL4.1.3或更新的数据库服务端 进行交互,但并不支持后期MySQL服务端提供的一些特性。

Note:

如果你是使用MySQL4.1.3或更新的服务端版本,强烈建议你使用mysqli 扩展替代它。

mysql扩展的源代码在PHP扩展目录ext/mysql下。

对于mysql扩展的更多信息,请参阅

什么是PHP的mysqli扩展?

mysqli扩展,我们有时称之为MySQL增强扩展,可以用于使用 MySQL4.1.3或更新版本中新的高级特性。mysqli扩展在PHP 5及以后版本中包含。

mysqli扩展有一系列的优势,相对于mysql扩展的提升主要有:

  • 面向对象接口

  • prepared语句支持(译注:关于prepare请参阅mysql相关文档)

  • 多语句执行支持

  • 事务支持

  • 增强的调试能力

  • 嵌入式服务支持

Note:

如果你使用MySQL4.1.3或更新版本,强烈建议你使用这个扩展。

在提供了面向对象接口的同时也提供了一个面向过程的接口。

mysqli扩展是使用PHP扩展框架构建的,它的源代码在PHP源码目录下的ext/mysqli中。

对于mysqli扩展的更多信息,请参阅

什么是PDO?

PHP数据对象,是PHP应用中的一个数据库抽象层规范。PDO提供了一个统一的API接口可以使得你的PHP应用不去关心具体要 连接的数据库服务器系统类型。也就是说,如果你使用PDO的API,可以在任何需要的时候无缝切换数据库服务器,比如从Firebird 到MySQL,仅仅需要修改很少的PHP代码。

其他数据库抽象层的例子包括Java应用中的JDBC以及Perl中的DBI。

当然,PDO也有它自己的先进性,比如一个干净的,简单的,可移植的API,它最主要的缺点是会限制让你不能使用 后期MySQL服务端提供所有的数据库高级特性。比如,PDO不允许使用MySQL支持的多语句执行。

PDO是基于PHP扩展框架实现的,它的源码在PHP源码目录的ext/pdo下。

PDO的更多信息,请参阅PDO

什么是PDO的MySQL驱动器?

PDO的MySQL驱动并不是一套API,至少从PHP程序员的角度来看是这样的。实际上,PDO的MySQL驱动处于PDO自己的下层, 提供了特定的Mysql功能。程序员直接调用PDO的API,而PDO使用了PDO的MySQL驱动完成与MySQL服务器端的交互。

PDO的MySQL驱动是众多PDO驱动中的一个。其他可用的PDO驱动包括Firebird,PostgreSQL等等。

PDO的MySQL驱动是基于PHP扩展框架实现的。它的源码在PHP源码目录下的ext/pdo_mysql。 它没有向PHP程序员暴露API。

PDO的MySQL扩展的更多信息请参阅

什么是PHP的MySQL Native 驱动?

为了与MySQL数据库服务端进行交互,mysql扩展,mysqli扩展, PDO MySQL驱动都使用了实现了必要的协议的底层库。以前,可用的库只有MySQL客户端库和libmysql

然而,libmysql包含的接口没有针对与PHP的应用交互进行优化,libmysql 是早期为C应用程序设计的。基于这个原因,MySQL Native驱动mysqlnd,作为libmysql的一个 针对PHP应用的修改版本被开发。

mysqlmysqli以及PDO Mysql驱动都可以各自配置使用 libmysql或者mysqlndmysqlnd作为一个专门设计 用于PHP系统的库,它在内存和速度上都比libmysql有很大提升。非常希望你去尝试这些提升。

Note:

MySQL Native驱动仅仅可以在MySQL服务端版本为4.1.3及以后版本才可以使用。

MySQL Native驱动是基于PHP扩展框架实现的。源代码位于PHP源码目录的ext/mysqlnd下。 它没有向PHP程序员暴露接口。

特性比较

下表比较了PHP中三种主要的MySQL连接方式的功能:

  PHP的mysqli扩展 PDO (使用PDO MySQL驱动和MySQL Native驱动) PHP的mysql扩展
引入的PHP版本 5.0 5.0 3.0之前
PHP5.x是否包含
MySQL开发状态 活跃 在PHP5.3中活跃 仅维护
在MySQL新项目中的建议使用程度 建议 - 首选 建议 不建议
API的字符集支持
服务端prepare语句的支持情况
客户端prepare语句的支持情况
存储过程支持情况
多语句执行支持情况 大多数
是否支持所有MySQL4.1以上功能 大多数

Quick start guide

目录

This quick start guide will help with choosing and gaining familiarity with the PHP MySQL API.

This quick start gives an overview on the mysqli extension. Code examples are provided for all major aspects of the API. Database concepts are explained to the degree needed for presenting concepts specific to MySQL.

Required: A familiarity with the PHP programming language, the SQL language, and basic knowledge of the MySQL server.

Dual procedural and object-oriented interface

The mysqli extension features a dual interface. It supports the procedural and object-oriented programming paradigm.

Users migrating from the old mysql extension may prefer the procedural interface. The procedural interface is similar to that of the old mysql extension. In many cases, the function names differ only by prefix. Some mysqli functions take a connection handle as their first argument, whereas matching functions in the old mysql interface take it as an optional last argument.

示例 #1 Easy migration from the old mysql extension

<?php
$mysqli = mysqli_connect("example.com", "user", "password", "database");
$res = mysqli_query($mysqli, "SELECT 'Please, do not use ' AS _msg FROM DUAL");
$row = mysqli_fetch_assoc($res);
echo $row['_msg'];

$mysql = mysql_connect("example.com", "user", "password");
mysql_select_db("test");
$res = mysql_query("SELECT 'the mysql extension for new developments.' AS _msg FROM DUAL", $mysql);
$row = mysql_fetch_assoc($res);
echo $row['_msg'];
?>

以上例程会输出:

Please, do not use the mysql extension for new developments.

The object-oriented interface

In addition to the classical procedural interface, users can choose to use the object-oriented interface. The documentation is organized using the object-oriented interface. The object-oriented interface shows functions grouped by their purpose, making it easier to get started. The reference section gives examples for both syntax variants.

There are no significant performance differences between the two interfaces. Users can base their choice on personal preference.

示例 #2 Object-oriented and procedural interface

<?php
$mysqli = mysqli_connect("example.com", "user", "password", "database");
if (mysqli_connect_errno()) {
    echo "Failed to connect to MySQL: " . mysqli_connect_error();
}

$res = mysqli_query($mysqli, "SELECT 'A world full of ' AS _msg FROM DUAL");
$row = mysqli_fetch_assoc($res);
echo $row['_msg'];

$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: " . $mysqli->connect_error;
}

$res = $mysqli->query("SELECT 'choices to please everybody.' AS _msg FROM DUAL");
$row = $res->fetch_assoc();
echo $row['_msg'];
?>

以上例程会输出:

A world full of choices to please everybody.

The object oriented interface is used for the quickstart because the reference section is organized that way.

Mixing styles

It is possible to switch between styles at any time. Mixing both styles is not recommended for code clarity and coding style reasons.

示例 #3 Bad coding style

<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: " . $mysqli->connect_error;
}

$res = mysqli_query($mysqli, "SELECT 'Possible but bad style.' AS _msg FROM DUAL");
if (!$res) {
    echo "Failed to run query: (" . $mysqli->errno . ") " . $mysqli->error;
}

if ($row = $res->fetch_assoc()) {
    echo $row['_msg'];
}
?>

以上例程会输出:

Possible but bad style.

See also

Connections

The MySQL server supports the use of different transport layers for connections. Connections use TCP/IP, Unix domain sockets or Windows named pipes.

The hostname localhost has a special meaning. It is bound to the use of Unix domain sockets. It is not possible to open a TCP/IP connection using the hostname localhost you must use 127.0.0.1 instead.

示例 #1 Special meaning of localhost

<?php
$mysqli = new mysqli("localhost", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
echo $mysqli->host_info . "\n";

$mysqli = new mysqli("127.0.0.1", "user", "password", "database", 3306);
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

echo $mysqli->host_info . "\n";
?>

以上例程会输出:

Localhost via UNIX socket
127.0.0.1 via TCP/IP

Connection parameter defaults

Depending on the connection function used, assorted parameters can be omitted. If a parameter is not provided, then the extension attempts to use the default values that are set in the PHP configuration file.

示例 #2 Setting defaults

mysqli.default_host=192.168.2.27
mysqli.default_user=root
mysqli.default_pw=""
mysqli.default_port=3306
mysqli.default_socket=/tmp/mysql.sock

The resulting parameter values are then passed to the client library that is used by the extension. If the client library detects empty or unset parameters, then it may default to the library built-in values.

Built-in connection library defaults

If the host value is unset or empty, then the client library will default to a Unix socket connection on localhost. If socket is unset or empty, and a Unix socket connection is requested, then a connection to the default socket on /tmp/mysql.sock is attempted.

On Windows systems, the host name . is interpreted by the client library as an attempt to open a Windows named pipe based connection. In this case the socket parameter is interpreted as the pipe name. If not given or empty, then the socket (pipe name) defaults to \\.\pipe\MySQL.

If neither a Unix domain socket based not a Windows named pipe based connection is to be established and the port parameter value is unset, the library will default to port 3306.

The mysqlnd library and the MySQL Client Library (libmysqlclient) implement the same logic for determining defaults.

Connection options

Connection options are available to, for example, set init commands which are executed upon connect, or for requesting use of a certain charset. Connection options must be set before a network connection is established.

For setting a connection option, the connect operation has to be performed in three steps: creating a connection handle with <span class="function">mysqli_init, setting the requested options using mysqli_options, and establishing the network connection with <span class="function">mysqli_real_connect.

Connection pooling

The mysqli extension supports persistent database connections, which are a special kind of pooled connections. By default, every database connection opened by a script is either explicitly closed by the user during runtime or released automatically at the end of the script. A persistent connection is not. Instead it is put into a pool for later reuse, if a connection to the same server using the same username, password, socket, port and default database is opened. Reuse saves connection overhead.

Every PHP process is using its own mysqli connection pool. Depending on the web server deployment model, a PHP process may serve one or multiple requests. Therefore, a pooled connection may be used by one or more scripts subsequently.

Persistent connection

If a unused persistent connection for a given combination of host, username, password, socket, port and default database can not be found in the connection pool, then mysqli opens a new connection. The use of persistent connections can be enabled and disabled using the PHP directive mysqli.allow_persistent. The total number of connections opened by a script can be limited with mysqli.max_links. The maximum number of persistent connections per PHP process can be restricted with mysqli.max_persistent. Please note, that the web server may spawn many PHP processes.

A common complain about persistent connections is that their state is not reset before reuse. For example, open and unfinished transactions are not automatically rolled back. But also, authorization changes which happened in the time between putting the connection into the pool and reusing it are not reflected. This may be seen as an unwanted side-effect. On the contrary, the name persistent may be understood as a promise that the state is persisted.

The mysqli extension supports both interpretations of a persistent connection: state persisted, and state reset before reuse. The default is reset. Before a persistent connection is reused, the mysqli extension implicitly calls mysqli_change_user to reset the state. The persistent connection appears to the user as if it was just opened. No artifacts from previous usages are visible.

The mysqli_change_user function is an expensive operation. For best performance, users may want to recompile the extension with the compile flag MYSQLI_NO_CHANGE_USER_ON_PCONNECT being set.

It is left to the user to choose between safe behavior and best performance. Both are valid optimization goals. For ease of use, the safe behavior has been made the default at the expense of maximum performance.

See also

Executing statements

Statements can be executed with the <span class="function">mysqli_query, <span class="function">mysqli_real_query and <span class="function">mysqli_multi_query functions. The <span class="function">mysqli_query function is the most common, and combines the executing statement with a buffered fetch of its result set, if any, in one call. Calling <span class="function">mysqli_query is identical to calling <span class="function">mysqli_real_query followed by <span class="function">mysqli_store_result.

示例 #1 Connecting to MySQL

<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

if (!$mysqli->query("DROP TABLE IF EXISTS test") ||
    !$mysqli->query("CREATE TABLE test(id INT)") ||
    !$mysqli->query("INSERT INTO test(id) VALUES (1)")) {
    echo "Table creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}
?>

Buffered result sets

After statement execution results can be retrieved at once to be buffered by the client or by read row by row. Client-side result set buffering allows the server to free resources associated with the statement results as early as possible. Generally speaking, clients are slow consuming result sets. Therefore, it is recommended to use buffered result sets. mysqli_query combines statement execution and result set buffering.

PHP applications can navigate freely through buffered results. Navigation is fast because the result sets are held in client memory. Please, keep in mind that it is often easier to scale by client than it is to scale the server.

示例 #2 Navigation through buffered results

<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

if (!$mysqli->query("DROP TABLE IF EXISTS test") ||
    !$mysqli->query("CREATE TABLE test(id INT)") ||
    !$mysqli->query("INSERT INTO test(id) VALUES (1), (2), (3)")) {
    echo "Table creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

$res = $mysqli->query("SELECT id FROM test ORDER BY id ASC");

echo "Reverse order...\n";
for ($row_no = $res->num_rows - 1; $row_no >= 0; $row_no--) {
    $res->data_seek($row_no);
    $row = $res->fetch_assoc();
    echo " id = " . $row['id'] . "\n";
}

echo "Result set order...\n";
$res->data_seek(0);
while ($row = $res->fetch_assoc()) {
    echo " id = " . $row['id'] . "\n";
}
?>

以上例程会输出:

Reverse order...
 id = 3
 id = 2
 id = 1
Result set order...
 id = 1
 id = 2
 id = 3

Unbuffered result sets

If client memory is a short resource and freeing server resources as early as possible to keep server load low is not needed, unbuffered results can be used. Scrolling through unbuffered results is not possible before all rows have been read.

示例 #3 Navigation through unbuffered results

<?php
$mysqli->real_query("SELECT id FROM test ORDER BY id ASC");
$res = $mysqli->use_result();

echo "Result set order...\n";
while ($row = $res->fetch_assoc()) {
    echo " id = " . $row['id'] . "\n";
}
?>

Result set values data types

The mysqli_query, <span class="function">mysqli_real_query and <span class="function">mysqli_multi_query functions are used to execute non-prepared statements. At the level of the MySQL Client Server Protocol, the command COM_QUERY and the text protocol are used for statement execution. With the text protocol, the MySQL server converts all data of a result sets into strings before sending. This conversion is done regardless of the SQL result set column data type. The mysql client libraries receive all column values as strings. No further client-side casting is done to convert columns back to their native types. Instead, all values are provided as PHP strings.

示例 #4 Text protocol returns strings by default

<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

if (!$mysqli->query("DROP TABLE IF EXISTS test") ||
    !$mysqli->query("CREATE TABLE test(id INT, label CHAR(1))") ||
    !$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'a')")) {
    echo "Table creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

$res = $mysqli->query("SELECT id, label FROM test WHERE id = 1");
$row = $res->fetch_assoc();

printf("id = %s (%s)\n", $row['id'], gettype($row['id']));
printf("label = %s (%s)\n", $row['label'], gettype($row['label']));
?>

以上例程会输出:

id = 1 (string)
label = a (string)

It is possible to convert integer and float columns back to PHP numbers by setting the MYSQLI_OPT_INT_AND_FLOAT_NATIVE connection option, if using the mysqlnd library. If set, the mysqlnd library will check the result set meta data column types and convert numeric SQL columns to PHP numbers, if the PHP data type value range allows for it. This way, for example, SQL INT columns are returned as integers.

示例 #5 Native data types with mysqlnd and connection option

<?php
$mysqli = mysqli_init();
$mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 1);
$mysqli->real_connect("example.com", "user", "password", "database");

if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

if (!$mysqli->query("DROP TABLE IF EXISTS test") ||
    !$mysqli->query("CREATE TABLE test(id INT, label CHAR(1))") ||
    !$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'a')")) {
    echo "Table creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

$res = $mysqli->query("SELECT id, label FROM test WHERE id = 1");
$row = $res->fetch_assoc();

printf("id = %s (%s)\n", $row['id'], gettype($row['id']));
printf("label = %s (%s)\n", $row['label'], gettype($row['label']));
?>

以上例程会输出:

id = 1 (integer)
label = a (string)

See also

  • mysqli::__construct
  • mysqli::init
  • mysqli::options
  • mysqli::real_connect
  • mysqli::query
  • mysqli::multi_query
  • mysqli::use_result
  • mysqli::store_result
  • mysqli_result::free

Prepared Statements

The MySQL database supports prepared statements. A prepared statement or a parameterized statement is used to execute the same statement repeatedly with high efficiency.

Basic workflow

The prepared statement execution consists of two stages: prepare and execute. At the prepare stage a statement template is sent to the database server. The server performs a syntax check and initializes server internal resources for later use.

The MySQL server supports using anonymous, positional placeholder with ?.

示例 #1 First stage: prepare

<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

/* Non-prepared statement */
if (!$mysqli->query("DROP TABLE IF EXISTS test") || !$mysqli->query("CREATE TABLE test(id INT)")) {
    echo "Table creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

/* Prepared statement, stage 1: prepare */
if (!($stmt = $mysqli->prepare("INSERT INTO test(id) VALUES (?)"))) {
    echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}
?>

Prepare is followed by execute. During execute the client binds parameter values and sends them to the server. The server creates a statement from the statement template and the bound values to execute it using the previously created internal resources.

示例 #2 Second stage: bind and execute

<?php
/* Prepared statement, stage 2: bind and execute */
$id = 1;
if (!$stmt->bind_param("i", $id)) {
    echo "Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error;
}

if (!$stmt->execute()) {
    echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}
?>

Repeated execution

A prepared statement can be executed repeatedly. Upon every execution the current value of the bound variable is evaluated and sent to the server. The statement is not parsed again. The statement template is not transferred to the server again.

示例 #3 INSERT prepared once, executed multiple times

<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

/* Non-prepared statement */
if (!$mysqli->query("DROP TABLE IF EXISTS test") || !$mysqli->query("CREATE TABLE test(id INT)")) {
    echo "Table creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

/* Prepared statement, stage 1: prepare */
if (!($stmt = $mysqli->prepare("INSERT INTO test(id) VALUES (?)"))) {
     echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

/* Prepared statement, stage 2: bind and execute */
$id = 1;
if (!$stmt->bind_param("i", $id)) {
    echo "Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error;
}

if (!$stmt->execute()) {
    echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}

/* Prepared statement: repeated execution, only data transferred from client to server */
for ($id = 2; $id < 5; $id++) {
    if (!$stmt->execute()) {
        echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
    }
}

/* explicit close recommended */
$stmt->close();

/* Non-prepared statement */
$res = $mysqli->query("SELECT id FROM test");
var_dump($res->fetch_all());
?>

以上例程会输出:

array(4) {
  [0]=>
  array(1) {
    [0]=>
    string(1) "1"
  }
  [1]=>
  array(1) {
    [0]=>
    string(1) "2"
  }
  [2]=>
  array(1) {
    [0]=>
    string(1) "3"
  }
  [3]=>
  array(1) {
    [0]=>
    string(1) "4"
  }
}

Every prepared statement occupies server resources. Statements should be closed explicitly immediately after use. If not done explicitly, the statement will be closed when the statement handle is freed by PHP.

Using a prepared statement is not always the most efficient way of executing a statement. A prepared statement executed only once causes more client-server round-trips than a non-prepared statement. This is why the SELECT is not run as a prepared statement above.

Also, consider the use of the MySQL multi-INSERT SQL syntax for INSERTs. For the example, multi-INSERT requires less round-trips between the server and client than the prepared statement shown above.

示例 #4 Less round trips using multi-INSERT SQL

<?php
if (!$mysqli->query("INSERT INTO test(id) VALUES (1), (2), (3), (4)")) {
    echo "Multi-INSERT failed: (" . $mysqli->errno . ") " . $mysqli->error;
}
?>

Result set values data types

The MySQL Client Server Protocol defines a different data transfer protocol for prepared statements and non-prepared statements. Prepared statements are using the so called binary protocol. The MySQL server sends result set data "as is" in binary format. Results are not serialized into strings before sending. The client libraries do not receive strings only. Instead, they will receive binary data and try to convert the values into appropriate PHP data types. For example, results from an SQL INT column will be provided as PHP integer variables.

示例 #5 Native datatypes

<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

if (!$mysqli->query("DROP TABLE IF EXISTS test") ||
    !$mysqli->query("CREATE TABLE test(id INT, label CHAR(1))") ||
    !$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'a')")) {
    echo "Table creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

$stmt = $mysqli->prepare("SELECT id, label FROM test WHERE id = 1");
$stmt->execute();
$res = $stmt->get_result();
$row = $res->fetch_assoc();

printf("id = %s (%s)\n", $row['id'], gettype($row['id']));
printf("label = %s (%s)\n", $row['label'], gettype($row['label']));
?>

以上例程会输出:

id = 1 (integer)
label = a (string)

This behavior differs from non-prepared statements. By default, non-prepared statements return all results as strings. This default can be changed using a connection option. If the connection option is used, there are no differences.

Fetching results using bound variables

Results from prepared statements can either be retrieved by binding output variables, or by requesting a <span class="classname">mysqli_result object.

Output variables must be bound after statement execution. One variable must be bound for every column of the statements result set.

示例 #6 Output variable binding

<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

if (!$mysqli->query("DROP TABLE IF EXISTS test") ||
    !$mysqli->query("CREATE TABLE test(id INT, label CHAR(1))") ||
    !$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'a')")) {
    echo "Table creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!($stmt = $mysqli->prepare("SELECT id, label FROM test"))) {
    echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$stmt->execute()) {
    echo "Execute failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

$out_id    = NULL;
$out_label = NULL;
if (!$stmt->bind_result($out_id, $out_label)) {
    echo "Binding output parameters failed: (" . $stmt->errno . ") " . $stmt->error;
}

while ($stmt->fetch()) {
    printf("id = %s (%s), label = %s (%s)\n", $out_id, gettype($out_id), $out_label, gettype($out_label));
}
?>

以上例程会输出:

id = 1 (integer), label = a (string)

Prepared statements return unbuffered result sets by default. The results of the statement are not implicitly fetched and transferred from the server to the client for client-side buffering. The result set takes server resources until all results have been fetched by the client. Thus it is recommended to consume results timely. If a client fails to fetch all results or the client closes the statement before having fetched all data, the data has to be fetched implicitly by mysqli.

It is also possible to buffer the results of a prepared statement using mysqli_stmt_store_result.

Fetching results using mysqli_result interface

Instead of using bound results, results can also be retrieved through the mysqli_result interface. <span class="function">mysqli_stmt_get_result returns a buffered result set.

示例 #7 Using mysqli_result to fetch results

<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

if (!$mysqli->query("DROP TABLE IF EXISTS test") ||
    !$mysqli->query("CREATE TABLE test(id INT, label CHAR(1))") ||
    !$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'a')")) {
    echo "Table creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!($stmt = $mysqli->prepare("SELECT id, label FROM test ORDER BY id ASC"))) {
    echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$stmt->execute()) {
     echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}

if (!($res = $stmt->get_result())) {
    echo "Getting result set failed: (" . $stmt->errno . ") " . $stmt->error;
}

var_dump($res->fetch_all());
?>

以上例程会输出:

array(1) {
  [0]=>
  array(2) {
    [0]=>
    int(1)
    [1]=>
    string(1) "a"
  }
}

Using the mysqli_result interface offers the additional benefit of flexible client-side result set navigation.

示例 #8 Buffered result set for flexible read out

<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

if (!$mysqli->query("DROP TABLE IF EXISTS test") ||
    !$mysqli->query("CREATE TABLE test(id INT, label CHAR(1))") ||
    !$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'a'), (2, 'b'), (3, 'c')")) {
    echo "Table creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!($stmt = $mysqli->prepare("SELECT id, label FROM test"))) {
    echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$stmt->execute()) {
     echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}

if (!($res = $stmt->get_result())) {
    echo "Getting result set failed: (" . $stmt->errno . ") " . $stmt->error;
}

for ($row_no = ($res->num_rows - 1); $row_no >= 0; $row_no--) {
    $res->data_seek($row_no);
    var_dump($res->fetch_assoc());
}
$res->close();
?>

以上例程会输出:

array(2) {
  ["id"]=>
  int(3)
  ["label"]=>
  string(1) "c"
}
array(2) {
  ["id"]=>
  int(2)
  ["label"]=>
  string(1) "b"
}
array(2) {
  ["id"]=>
  int(1)
  ["label"]=>
  string(1) "a"
}

Escaping and SQL injection

Bound variables are sent to the server separately from the query and thus cannot interfere with it. The server uses these values directly at the point of execution, after the statement template is parsed. Bound parameters do not need to be escaped as they are never substituted into the query string directly. A hint must be provided to the server for the type of bound variable, to create an appropriate conversion. See the mysqli_stmt_bind_param function for more information.

Such a separation sometimes considered as the only security feature to prevent SQL injection, but the same degree of security can be achieved with non-prepared statements, if all the values are formatted correctly. It should be noted that correct formatting is not the same as escaping and involves more logic than simple escaping. Thus, prepared statements are simply a more convenient and less error-prone approach to this element of database security.

Client-side prepared statement emulation

The API does not include emulation for client-side prepared statement emulation.

Quick prepared - non-prepared statement comparison

The table below compares server-side prepared and non-prepared statements.

  Prepared Statement Non-prepared statement
Client-server round trips, SELECT, single execution 2 1
Statement string transferred from client to server 1 1
Client-server round trips, SELECT, repeated (n) execution 1 + n n
Statement string transferred from client to server 1 template, n times bound parameter, if any n times together with parameter, if any
Input parameter binding API Yes, automatic input escaping No, manual input escaping
Output variable binding API Yes No
Supports use of mysqli_result API Yes, use mysqli_stmt_get_result Yes
Buffered result sets Yes, use mysqli_stmt_get_result or binding with mysqli_stmt_store_result Yes, default of mysqli_query
Unbuffered result sets Yes, use output binding API Yes, use mysqli_real_query with mysqli_use_result
MySQL Client Server protocol data transfer flavor Binary protocol Text protocol
Result set values SQL data types Preserved when fetching Converted to string or preserved when fetching
Supports all SQL statements Recent MySQL versions support most but not all Yes

See also

  • mysqli::__construct
  • mysqli::query
  • mysqli::prepare
  • mysqli_stmt::prepare
  • mysqli_stmt::execute
  • mysqli_stmt::bind_param
  • mysqli_stmt::bind_result

Stored Procedures

The MySQL database supports stored procedures. A stored procedure is a subroutine stored in the database catalog. Applications can call and execute the stored procedure. The CALL SQL statement is used to execute a stored procedure.

Parameter

Stored procedures can have IN, INOUT and OUT parameters, depending on the MySQL version. The mysqli interface has no special notion for the different kinds of parameters.

IN parameter

Input parameters are provided with the CALL statement. Please, make sure values are escaped correctly.

示例 #1 Calling a stored procedure

<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

if (!$mysqli->query("DROP TABLE IF EXISTS test") || !$mysqli->query("CREATE TABLE test(id INT)")) {
    echo "Table creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$mysqli->query("DROP PROCEDURE IF EXISTS p") ||
    !$mysqli->query("CREATE PROCEDURE p(IN id_val INT) BEGIN INSERT INTO test(id) VALUES(id_val); END;")) {
    echo "Stored procedure creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$mysqli->query("CALL p(1)")) {
    echo "CALL failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!($res = $mysqli->query("SELECT id FROM test"))) {
    echo "SELECT failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

var_dump($res->fetch_assoc());
?>

以上例程会输出:

array(1) {
  ["id"]=>
  string(1) "1"
}

INOUT/OUT parameter

The values of INOUT/OUT parameters are accessed using session variables.

示例 #2 Using session variables

<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

if (!$mysqli->query("DROP PROCEDURE IF EXISTS p") ||
    !$mysqli->query('CREATE PROCEDURE p(OUT msg VARCHAR(50)) BEGIN SELECT "Hi!" INTO msg; END;')) {
    echo "Stored procedure creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}


if (!$mysqli->query("SET @msg = ''") || !$mysqli->query("CALL p(@msg)")) {
    echo "CALL failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!($res = $mysqli->query("SELECT @msg as _p_out"))) {
    echo "Fetch failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

$row = $res->fetch_assoc();
echo $row['_p_out'];
?>

以上例程会输出:

Hi!

Application and framework developers may be able to provide a more convenient API using a mix of session variables and databased catalog inspection. However, please note the possible performance impact of a custom solution based on catalog inspection.

Handling result sets

Stored procedures can return result sets. Result sets returned from a stored procedure cannot be fetched correctly using <span class="function">mysqli_query. The <span class="function">mysqli_query function combines statement execution and fetching the first result set into a buffered result set, if any. However, there are additional stored procedure result sets hidden from the user which cause <span class="function">mysqli_query to fail returning the user expected result sets.

Result sets returned from a stored procedure are fetched using <span class="function">mysqli_real_query or <span class="function">mysqli_multi_query. Both functions allow fetching any number of result sets returned by a statement, such as CALL. Failing to fetch all result sets returned by a stored procedure causes an error.

示例 #3 Fetching results from stored procedures

<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

if (!$mysqli->query("DROP TABLE IF EXISTS test") ||
    !$mysqli->query("CREATE TABLE test(id INT)") ||
    !$mysqli->query("INSERT INTO test(id) VALUES (1), (2), (3)")) {
    echo "Table creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$mysqli->query("DROP PROCEDURE IF EXISTS p") ||
    !$mysqli->query('CREATE PROCEDURE p() READS SQL DATA BEGIN SELECT id FROM test; SELECT id + 1 FROM test; END;')) {
    echo "Stored procedure creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$mysqli->multi_query("CALL p()")) {
    echo "CALL failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

do {
    if ($res = $mysqli->store_result()) {
        printf("---\n");
        var_dump($res->fetch_all());
        $res->free();
    } else {
        if ($mysqli->errno) {
            echo "Store failed: (" . $mysqli->errno . ") " . $mysqli->error;
        }
    }
} while ($mysqli->more_results() && $mysqli->next_result());
?>

以上例程会输出:

---
array(3) {
  [0]=>
  array(1) {
    [0]=>
    string(1) "1"
  }
  [1]=>
  array(1) {
    [0]=>
    string(1) "2"
  }
  [2]=>
  array(1) {
    [0]=>
    string(1) "3"
  }
}
---
array(3) {
  [0]=>
  array(1) {
    [0]=>
    string(1) "2"
  }
  [1]=>
  array(1) {
    [0]=>
    string(1) "3"
  }
  [2]=>
  array(1) {
    [0]=>
    string(1) "4"
  }
}

Use of prepared statements

No special handling is required when using the prepared statement interface for fetching results from the same stored procedure as above. The prepared statement and non-prepared statement interfaces are similar. Please note, that not every MYSQL server version may support preparing the CALL SQL statement.

示例 #4 Stored Procedures and Prepared Statements

<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

if (!$mysqli->query("DROP TABLE IF EXISTS test") ||
    !$mysqli->query("CREATE TABLE test(id INT)") ||
    !$mysqli->query("INSERT INTO test(id) VALUES (1), (2), (3)")) {
    echo "Table creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$mysqli->query("DROP PROCEDURE IF EXISTS p") ||
    !$mysqli->query('CREATE PROCEDURE p() READS SQL DATA BEGIN SELECT id FROM test; SELECT id + 1 FROM test; END;')) {
    echo "Stored procedure creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!($stmt = $mysqli->prepare("CALL p()"))) {
    echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$stmt->execute()) {
    echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}

do {
    if ($res = $stmt->get_result()) {
        printf("---\n");
        var_dump(mysqli_fetch_all($res));
        mysqli_free_result($res);
    } else {
        if ($stmt->errno) {
            echo "Store failed: (" . $stmt->errno . ") " . $stmt->error;
        }
    }
} while ($stmt->more_results() && $stmt->next_result());
?>

Of course, use of the bind API for fetching is supported as well.

示例 #5 Stored Procedures and Prepared Statements using bind API

<?php
if (!($stmt = $mysqli->prepare("CALL p()"))) {
    echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$stmt->execute()) {
    echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}

do {

    $id_out = NULL;
    if (!$stmt->bind_result($id_out)) {
        echo "Bind failed: (" . $stmt->errno . ") " . $stmt->error;
    }

    while ($stmt->fetch()) {
        echo "id = $id_out\n";
    }
} while ($stmt->more_results() && $stmt->next_result());
?>

See also

  • mysqli::query
  • mysqli::multi_query
  • mysqli_result::next-result
  • mysqli_result::more-results

Multiple Statements

MySQL optionally allows having multiple statements in one statement string. Sending multiple statements at once reduces client-server round trips but requires special handling.

Multiple statements or multi queries must be executed with <span class="function">mysqli_multi_query. The individual statements of the statement string are separated by semicolon. Then, all result sets returned by the executed statements must be fetched.

The MySQL server allows having statements that do return result sets and statements that do not return result sets in one multiple statement.

示例 #1 Multiple Statements

<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

if (!$mysqli->query("DROP TABLE IF EXISTS test") || !$mysqli->query("CREATE TABLE test(id INT)")) {
    echo "Table creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

$sql = "SELECT COUNT(*) AS _num FROM test; ";
$sql.= "INSERT INTO test(id) VALUES (1); ";
$sql.= "SELECT COUNT(*) AS _num FROM test; ";

if (!$mysqli->multi_query($sql)) {
    echo "Multi query failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

do {
    if ($res = $mysqli->store_result()) {
        var_dump($res->fetch_all(MYSQLI_ASSOC));
        $res->free();
    }
} while ($mysqli->more_results() && $mysqli->next_result());
?>

以上例程会输出:

array(1) {
  [0]=>
  array(1) {
    ["_num"]=>
    string(1) "0"
  }
}
array(1) {
  [0]=>
  array(1) {
    ["_num"]=>
    string(1) "1"
  }
}

Security considerations

The API functions mysqli_query and <span class="function">mysqli_real_query do not set a connection flag necessary for activating multi queries in the server. An extra API call is used for multiple statements to reduce the likeliness of accidental SQL injection attacks. An attacker may try to add statements such as ; DROP DATABASE mysql or ; SELECT SLEEP(999). If the attacker succeeds in adding SQL to the statement string but mysqli_multi_query is not used, the server will not execute the second, injected and malicious SQL statement.

示例 #2 SQL Injection

<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
$res    = $mysqli->query("SELECT 1; DROP TABLE mysql.user");
if (!$res) {
    echo "Error executing query: (" . $mysqli->errno . ") " . $mysqli->error;
}
?>

以上例程会输出:

Error executing query: (1064) You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the right syntax 
to use near 'DROP TABLE mysql.user' at line 1

Prepared statements

Use of the multiple statement with prepared statements is not supported.

See also

  • mysqli::query
  • mysqli::multi_query
  • mysqli_result::next-result
  • mysqli_result::more-results

API support for transactions

The MySQL server supports transactions depending on the storage engine used. Since MySQL 5.5, the default storage engine is InnoDB. InnoDB has full ACID transaction support.

Transactions can either be controlled using SQL or API calls. It is recommended to use API calls for enabling and disabling the autocommit mode and for committing and rolling back transactions.

示例 #1 Setting autocommit mode with SQL and through the API

<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("example.com", "user", "password", "database");

/* Recommended: using API to control transactional settings */
$mysqli->autocommit(false);

/* Won't be monitored and recognized by the replication and the load balancing plugin */
$mysqli->query('SET AUTOCOMMIT = 0');

Optional feature packages, such as the replication and load balancing plugin, can easily monitor API calls. The replication plugin offers transaction aware load balancing, if transactions are controlled with API calls. Transaction aware load balancing is not available if SQL statements are used for setting autocommit mode, committing or rolling back a transaction.

示例 #2 Commit and rollback

<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("example.com", "user", "password", "database");
$mysqli->autocommit(false);

$mysqli->query("INSERT INTO test(id) VALUES (1)");
$mysqli->rollback();

$mysqli->query("INSERT INTO test(id) VALUES (2)");
$mysqli->commit();

Please note, that the MySQL server cannot roll back all statements. Some statements cause an implicit commit.

See also

  • mysqli::autocommit
  • mysqli::begin_transaction
  • mysqli::commit
  • mysqli::rollback

Metadata

A MySQL result set contains metadata. The metadata describes the columns found in the result set. All metadata sent by MySQL is accessible through the mysqli interface. The extension performs no or negligible changes to the information it receives. Differences between MySQL server versions are not aligned.

Meta data is access through the <span class="classname">mysqli_result interface.

示例 #1 Accessing result set meta data

<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

$res = $mysqli->query("SELECT 1 AS _one, 'Hello' AS _two FROM DUAL");
var_dump($res->fetch_fields());
?>

以上例程会输出:

array(2) {
  [0]=>
  object(stdClass)#3 (13) {
    ["name"]=>
    string(4) "_one"
    ["orgname"]=>
    string(0) ""
    ["table"]=>
    string(0) ""
    ["orgtable"]=>
    string(0) ""
    ["def"]=>
    string(0) ""
    ["db"]=>
    string(0) ""
    ["catalog"]=>
    string(3) "def"
    ["max_length"]=>
    int(1)
    ["length"]=>
    int(1)
    ["charsetnr"]=>
    int(63)
    ["flags"]=>
    int(32897)
    ["type"]=>
    int(8)
    ["decimals"]=>
    int(0)
  }
  [1]=>
  object(stdClass)#4 (13) {
    ["name"]=>
    string(4) "_two"
    ["orgname"]=>
    string(0) ""
    ["table"]=>
    string(0) ""
    ["orgtable"]=>
    string(0) ""
    ["def"]=>
    string(0) ""
    ["db"]=>
    string(0) ""
    ["catalog"]=>
    string(3) "def"
    ["max_length"]=>
    int(5)
    ["length"]=>
    int(5)
    ["charsetnr"]=>
    int(8)
    ["flags"]=>
    int(1)
    ["type"]=>
    int(253)
    ["decimals"]=>
    int(31)
  }
}

Prepared statements

Meta data of result sets created using prepared statements are accessed the same way. A suitable mysqli_result handle is returned by <span class="function">mysqli_stmt_result_metadata.

示例 #2 Prepared statements metadata

<?php
$stmt = $mysqli->prepare("SELECT 1 AS _one, 'Hello' AS _two FROM DUAL");
$stmt->execute();
$res = $stmt->result_metadata();
var_dump($res->fetch_fields());
?>

See also

  • mysqli::query
  • mysqli_result::fetch_fields

安装/配置

目录

需求

要使用 mysqli 相关的函数, 你必须以启用 mysqli 扩展的方式编译 PHP。

MySQL 8

使用 PHP 7.1.16 之前的版本或者 PHP 7.2(PHP 7.2.4 之前的版本), 需要将 MySQL 服务器的默认密码插件设置为:mysql_native_password。 否则,当你连接的时候就会看到类似这样的错误: The server requested authentication method unknown to the client [caching_sha2_password]。 即使你未使用 caching_sha2_password 也会这样。

发生这种错误的原因是,MySQL 8 服务器默认会使用 caching_sha2_password 扩展, 老版本的 PHP 驱动(mysqlnd)无法识别这个扩展。 所以需要在 MySQL 的配置文件 my.cnf 中,设置 default_authentication_plugin=mysql_native_password。 在后续的 PHP 发行版本中,会提供对 MySQL caching_sha2_password 扩展的支持。 目前只有 mysql_xdevapi 扩展是 支持 MySQL 的 caching_sha2_password 扩展的。

安装

mysqli扩展在PHP5.0.0中被引入。Mysql Native驱动在PHP5.3.0版本中被引入。

在linux上安装

通用的Unix分发包中会包含PHP可安装的二进制版本。虽然这些二进制版本通常会被构建为支持启用mysql扩展的, 蚕食扩展库自身可能需要依赖其他附加包的安装。因此对包管理的检查会比选择可用的发行版本更重要。

除非你的Unix分发包包含的PHP二进制包的mysqli扩展可用,否则你就需要 从源码构建PHP。如果你希望使用mysql扩展,从PHP源代码构建允许你这样做,并且可以指定每个扩展 使用什么客户端库。

使用Mysql Native Driver 是推荐的选项,会提升性能并且会带来一些Mysql Client Library不允许的访问特性。 什么是Mysql自然驱动器?中对Mysql Native Driver 的优势做了一个简要概述。

/path/to/mysql_config代表了要用来编译mysql客户端/连接mysql服务端的mysql_config程序位置。

PHP 版本 默认 配置选项: mysqlnd 配置选项: libmysql 更新日志
5.0.x, 5.1.x, 5.2.x libmysql 不适用 --with-mysqli=/path/to/mysql_config  
5.3.x libmysql --with-mysqli=mysqlnd --with-mysqli=/path/to/mysql_config mysqlnd is now supported
5.4.x mysqlnd --with-mysqli --with-mysqli=/path/to/mysql_config mysqlnd is now the default

请注意Mysql扩展和客户端库是可以自由混合的。比如,可以使用libmysql这个mysql客户端库来启用Mysql扩展,使用 Mysql Native Driver来配置mysqli扩展。所有的扩展和客户端库的顺序都是可能的。

下面的示例使用Mysql Client Library(libmysql)构建了mysql扩展,并且mysqli和 PDO Mysql扩展使用Mysql Native Dirver(作为客户端库):

./configure --with-mysql=/usr/bin/mysql_config  \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd
[other options]

在windows系统安装

在windows上,PHP通常使用二进制安装包进行安装。

PHP 5.0, 5.1, 5.2

当PHP安装后,如果期望使用则可以通过一些配置来开启mysqli并指定客户端库。

mysqli扩展默认并不会开启,因此php.iniphp_mysqli.dll这个DLL 必须开启。为此你需要找到php.ini文件(通常在c:\php),并且你需要确认删除了 [PHP_MYSQLI]部分中的extension=php_mysqli.dll一行行首的注释符号(分号)。

另外,如果你希望使用Mysql client library(libmysql)作为mysqli的驱动器,你需要确保PHP可以访问 客户端库的文件。Mysql Client Library作为文件libmysql.dll包含在windows的PHP分发包中。 这个文件需要在windows系统的PATH环境变量中才可以被成功加载。查看FAQ文档 怎样增加我的PHP目录到Windows的PATH中了解怎样配置环境变量PATH。 把libmysql.dll拷贝到Windows的系统目录(通常是c:\Windows\system)也是适用的, 通常系统目录默认就在系统的PATH环境变量下。然而,我们强烈反对这种做法。

就像开启任何PHP扩展(比如php_mysqli.dll),PHP指令 extension_dir可以被设置为PHP扩展位置的目录路径。 查看windows安装介绍手册。关于此的一个例子是PHP 5中 extension_dir指令的值是c:\php\ext

Note:

如果启动web服务器的时候发生了类似下面这样的错误"Unable to load dynamic library './php_mysqli.dll'", 这就是因为在系统中无法找到php_mysqli.dll或者libmysql.dll

PHP 5.3.0+

在windows上,对于PHP 5.3或更新版本,mysqli扩展默认开启并使用Mysql Native Driver。 这就是说你不需要担心关于访问libmysql.dll的配置。

运行时配置

这些函数的行为受 php.ini 中的设置影响。

名字 默认 可修改范围 更新日志
mysqli.allow_local_infile "0" PHP_INI_SYSTEM 自PHP 5.2.4起可用。在 PHP 7.2.16 和 7.3.3 之前,默认值为 "1"
mysqli.local_infile_directory   PHP_INI_SYSTEM  
mysqli.allow_persistent "1" PHP_INI_SYSTEM 自PHP 5.3.0起可用。
mysqli.max_persistent "-1" PHP_INI_SYSTEM 自PHP 5.3.0起可用。
mysqli.max_links "-1" PHP_INI_SYSTEM  
mysqli.default_port "3306" PHP_INI_ALL  
mysqli.default_socket NULL PHP_INI_ALL  
mysqli.default_host NULL PHP_INI_ALL  
mysqli.default_user NULL PHP_INI_ALL 自PHP 5.0.0起可用。
mysqli.default_pw NULL PHP_INI_ALL  
mysqli.reconnect "0" PHP_INI_SYSTEM  
mysqli.rollback_on_cached_plink TRUE PHP_INI_SYSTEM 自 PHP 5.6.0 起可用。

关于前面出现的PHP_INI_*系列常量的详细定义,请参阅配置的修改一章。

这是配置指令的简短说明。

mysqli.allow_local_infile integer
允许Mysql的Load Data语句访问PHP角度看的本地文件。

mysqli.local_infile_directory string
限制加载 LOCAL DATA 文件为指定的目录。

mysqli.allow_persistent integer
开启使用<span class="function">mysqli_connect函数创建持久化连接的能力。

mysqli.max_persistent integer
可以创建的持久化连接的最大数量,设置为0表明不限制。

mysqli.max_links integer
每个进程中Mysql连接的最大数量。

mysqli.default_port integer
当没有指定其他端口号时使用的默认的用于连接数据库服务器的TCP端口号。如果没有设置默认值, 端口号将会按照顺序从环境变量MYSQL_TCP_PORT/etc/services 文件中的mysql-tcp条目或编译期的MYSQL_PORT常量等位置获取。 Win32仅使用MYSQL_PORT常量。

mysqli.default_socket string
当连接到本地数据库服务器时如果没有指定其他socket名称,使用的默认socket名称。

mysqli.default_host string
当连接到数据库服务器时, 如果没有指定其他主机地址,使用的默认服务器主机。

mysqli.default_user string
当连接到数据库服务器时,如果没有指定其他用户名,使用的默认用户名。

mysqli.default_pw string
当连接到数据库服务器时,如果没有指定其他密码,使用的默认密码。

mysqli.reconnect integer
连接丢失时是否自动重新连接。

Note: mysqlnd 驱动会此忽略 php.ini 设置。

mysqli.rollback_on_cached_plink bool
If this option is enabled, closing a persistent connection will rollback any pending transactions of this connection before it is put back into the persistent connection pool. Otherwise, pending transactions will be rolled back only when the connection is reused, or when it is actually closed.

用户不能通过API调用或运行时配置来设置MYSQL_OPT_READ_TIMEOUT。 注意,如果可能这样做那么libmysqlclient和流对MYSQL_OPT_READ_TIMEOUT 的值将会有不同的解释。

资源类型

此扩展没有定义资源类型。

mysqli 扩展和持久化连接

从 PHP 5.3 mysqli 扩展开始支持持久化连接。 持久化连接已经在 PDO MYSQL 和 ext/mysql 中提供支持。 持久化连接的目的在于重用客户端到服务器之间的连接, 而不是每次在需要的时候都重新建立一个连接。 由于持久化连接可以将已经建立的连接缓存起来,以备后续的使用, 所以省去了建立新的连接的开销, 因此可以带来性能上的提升。

不像 mysql 扩展,mysqli 没有提供一个特殊的方法用于打开持久化连接。 需要打开一个持久化连接时,你必须在 连接时在主机名前增加p:

使用持久化连接也会存在一些风险, 因为在缓存中的连接可能处于一种不可预测的状态。 例如,如果客户端未能正常关闭连接, 可能在这个连接上残留了对库表的锁, 那么当这个连接被其他请求重用的时候,这个连接还是处于 “有锁的状态”。 所以,如果要很好的使用持久化连接,那么要求代码在和数据库进行交互的时候, 确保做好清理工作,保证被缓存的连接是一个干净的,没有残留的状态。

mysqli 扩展的持久化连接提供了内建的清理处理代码。 mysqli 所做的清理工作包括:

  • 回滚处于活动状态的事务

  • 关闭并且删除临时表

  • 对表解锁

  • 重置会话变量

  • 关闭预编译 SQL 语句(在PHP中经常发生)

  • 关闭处理程序

  • 释放通过 GET_LOCK 获得的锁

这确保了将连接返回到连接池的时候, 它处于一种“干净”的状态,可以被其他客户端进程所使用。

mysqli 扩展 通过自动调用 C-API 函数 mysql_change_user() 来完成这个清理工作。

自动清理的特性有优点也有缺点。 优点是程序员不再需要担心附加的清理代码, 因为它们会自动调用。 然而缺点就是 性能 可能会 慢一点, 因为每次从连接池返回一个连接都需要执行这些清理代码。

这个自动清理的代码可以通过在编译 php 时定义 MYSQLI_NO_CHANGE_USER_ON_PCONNECT 来关闭。

Note:

mysqli 扩展在使用 MySQL Native Driver 或 Mysql Client Library(libmysql)时都支持持久化连接。

预定义常量

下列常量由此扩展定义,且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

MYSQLI_READ_DEFAULT_GROUP
Read options from the named group from my.cnf or the file specified with MYSQLI_READ_DEFAULT_FILE

MYSQLI_READ_DEFAULT_FILE
Read options from the named option file instead of from my.cnf

MYSQLI_OPT_CONNECT_TIMEOUT
Connect timeout in seconds

MYSQLI_OPT_LOCAL_INFILE
Enables command LOAD LOCAL INFILE

MYSQLI_INIT_COMMAND
Command to execute when connecting to MySQL server. Will automatically be re-executed when reconnecting.

MYSQLI_CLIENT_SSL
Use SSL (encrypted protocol). This option should not be set by application programs; it is set internally in the MySQL client library

MYSQLI_CLIENT_COMPRESS
Use compression protocol

MYSQLI_CLIENT_INTERACTIVE
Allow interactive_timeout seconds (instead of wait_timeout seconds) of inactivity before closing the connection. The client's session wait_timeout variable will be set to the value of the session interactive_timeout variable.

MYSQLI_CLIENT_IGNORE_SPACE
Allow spaces after function names. Makes all functions names reserved words.

MYSQLI_CLIENT_NO_SCHEMA
Don't allow the db_name.tbl_name.col_name syntax.

MYSQLI_CLIENT_MULTI_QUERIES
Allows multiple semicolon-delimited queries in a single <span class="function">mysqli_query call.

MYSQLI_STORE_RESULT
For using buffered resultsets

MYSQLI_USE_RESULT
For using unbuffered resultsets

MYSQLI_ASSOC
Columns are returned into the array having the fieldname as the array index.

MYSQLI_NUM
Columns are returned into the array having an enumerated index.

MYSQLI_BOTH
Columns are returned into the array having both a numerical index and the fieldname as the associative index.

MYSQLI_NOT_NULL_FLAG
Indicates that a field is defined as NOT NULL

MYSQLI_PRI_KEY_FLAG
Field is part of a primary index

MYSQLI_UNIQUE_KEY_FLAG
Field is part of a unique index.

MYSQLI_MULTIPLE_KEY_FLAG
Field is part of an index.

MYSQLI_BLOB_FLAG
Field is defined as BLOB

MYSQLI_UNSIGNED_FLAG
Field is defined as UNSIGNED

MYSQLI_ZEROFILL_FLAG
Field is defined as ZEROFILL

MYSQLI_AUTO_INCREMENT_FLAG
Field is defined as AUTO_INCREMENT

MYSQLI_TIMESTAMP_FLAG
Field is defined as TIMESTAMP

MYSQLI_SET_FLAG
Field is defined as SET

MYSQLI_NUM_FLAG
Field is defined as NUMERIC

MYSQLI_PART_KEY_FLAG
Field is part of an multi-index

MYSQLI_GROUP_FLAG
Field is part of GROUP BY

MYSQLI_TYPE_DECIMAL
Field is defined as DECIMAL

MYSQLI_TYPE_NEWDECIMAL
Precision math DECIMAL or NUMERIC field (MySQL 5.0.3 and up)

MYSQLI_TYPE_BIT
Field is defined as BIT (MySQL 5.0.3 and up)

MYSQLI_TYPE_TINY
Field is defined as TINYINT

MYSQLI_TYPE_SHORT
Field is defined as SMALLINT

MYSQLI_TYPE_LONG
Field is defined as INT

MYSQLI_TYPE_FLOAT
Field is defined as FLOAT

MYSQLI_TYPE_DOUBLE
Field is defined as DOUBLE

MYSQLI_TYPE_NULL
Field is defined as DEFAULT NULL

MYSQLI_TYPE_TIMESTAMP
Field is defined as TIMESTAMP

MYSQLI_TYPE_LONGLONG
Field is defined as BIGINT

MYSQLI_TYPE_INT24
Field is defined as MEDIUMINT

MYSQLI_TYPE_DATE
Field is defined as DATE

MYSQLI_TYPE_TIME
Field is defined as TIME

MYSQLI_TYPE_DATETIME
Field is defined as DATETIME

MYSQLI_TYPE_YEAR
Field is defined as YEAR

MYSQLI_TYPE_NEWDATE
Field is defined as DATE

MYSQLI_TYPE_INTERVAL
Field is defined as INTERVAL

MYSQLI_TYPE_ENUM
Field is defined as ENUM

MYSQLI_TYPE_SET
Field is defined as SET

MYSQLI_TYPE_TINY_BLOB
Field is defined as TINYBLOB

MYSQLI_TYPE_MEDIUM_BLOB
Field is defined as MEDIUMBLOB

MYSQLI_TYPE_LONG_BLOB
Field is defined as LONGBLOB

MYSQLI_TYPE_BLOB
Field is defined as BLOB

MYSQLI_TYPE_VAR_STRING
Field is defined as VARCHAR

MYSQLI_TYPE_STRING
Field is defined as STRING

MYSQLI_TYPE_CHAR
Field is defined as CHAR

MYSQLI_TYPE_GEOMETRY
Field is defined as GEOMETRY

MYSQLI_NEED_DATA
More data available for bind variable

MYSQLI_NO_DATA
No more data available for bind variable

MYSQLI_DATA_TRUNCATED
Data truncation occurred. Available since PHP 5.1.0 and MySQL 5.0.5.

MYSQLI_ENUM_FLAG
Field is defined as ENUM. Available since PHP 5.3.0.

MYSQLI_CURSOR_TYPE_FOR_UPDATE

MYSQLI_CURSOR_TYPE_NO_CURSOR

MYSQLI_CURSOR_TYPE_READ_ONLY

MYSQLI_CURSOR_TYPE_SCROLLABLE

MYSQLI_STMT_ATTR_CURSOR_TYPE

MYSQLI_STMT_ATTR_PREFETCH_ROWS

MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH

MYSQLI_SET_CHARSET_NAME

MYSQLI_REPORT_INDEX
Report if no index or bad index was used in a query.

MYSQLI_REPORT_ERROR
Report errors from mysqli function calls.

MYSQLI_REPORT_STRICT
Throw a mysqli_sql_exception for errors instead of warnings.

MYSQLI_REPORT_ALL
Set all options on (report all).

MYSQLI_REPORT_OFF
Turns reporting off.

MYSQLI_DEBUG_TRACE_ENABLED
Is set to 1 if mysqli_debug functionality is enabled.

MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED

MYSQLI_SERVER_QUERY_NO_INDEX_USED

MYSQLI_REFRESH_GRANT
Refreshes the grant tables.

MYSQLI_REFRESH_LOG
Flushes the logs, like executing the FLUSH LOGS SQL statement.

MYSQLI_REFRESH_TABLES
Flushes the table cache, like executing the FLUSH TABLES SQL statement.

MYSQLI_REFRESH_HOSTS
Flushes the host cache, like executing the FLUSH HOSTS SQL statement.

MYSQLI_REFRESH_STATUS
Reset the status variables, like executing the FLUSH STATUS SQL statement.

MYSQLI_REFRESH_THREADS
Flushes the thread cache.

MYSQLI_REFRESH_SLAVE
On a slave replication server: resets the master server information, and restarts the slave. Like executing the RESET SLAVE SQL statement.

MYSQLI_REFRESH_MASTER
On a master replication server: removes the binary log files listed in the binary log index, and truncates the index file. Like executing the RESET MASTER SQL statement.

Notes

Some implementation notes:

  1. Support was added for MYSQL_TYPE_GEOMETRY to the MySQLi extension in PHP 5.3.

  2. Note there are different internal implementations within libmysqlclient and mysqlnd for handling columns of type MYSQL_TYPE_GEOMETRY. Generally speaking, mysqlnd will allocate significantly less memory. For example, if there is a POINT column in a result set, libmysqlclient may pre-allocate up to 4GB of RAM although less than 50 bytes are needed for holding a POINT column in memory. Memory allocation is much lower, less than 50 bytes, if using mysqlnd.

MySQLi 扩展的功能概述

mysqli 方法的概述

mysqli 类

面向对象接口

面向过程接口

别名 (勿使用)

描述

属性

$mysqli::affected_rows

mysqli_affected_rows

N/A

获取上次 Mysql 操作受影响的行数

$mysqli::client_info

mysqli_get_client_info

N/A

返回 Mysql 客户端版本信息,类型为 string

$mysqli::client_version

mysqli_get_client_version

N/A

返回 Mysql 客户端版本信息,类型为 integer

$mysqli::connect_errno

mysqli_connect_errno

N/A

返回最后一次连接数据库的错误代码

$mysqli::connect_error

mysqli_connect_error

N/A

返回最后一次连接数据库的错误描述,类型为字符串

$mysqli::errno

mysqli_errno

N/A

返回最近一次函数调用所产生的错误代码

$mysqli::error

mysqli_error

N/A

返回最近一次错误代码的描述,类型是字符串

$mysqli::field_count

mysqli_field_count

N/A

返回最近一次查询中,包含的列的数量

$mysqli::host_info

mysqli_get_host_info

N/A

返回字符串,表示数据库连接所使用的类型

$mysqli::protocol_version

mysqli_get_proto_info

N/A

返回使用的 MySQL 协议的版本信息

$mysqli::server_info

mysqli_get_server_info

N/A

返回 MySQL 服务器的版本

$mysqli::server_version

mysqli_get_server_version

N/A

返回 MySQL 服务器的版本,类型为 integer

$mysqli::info

mysqli_info

N/A

获取最近一次数据库查询的信息

$mysqli::insert_id

mysqli_insert_id

N/A

返回上次查询中所使用的自动生成的 ID

$mysqli::sqlstate

mysqli_sqlstate

N/A

返回上次 MySQL 操作的数据库状态错误(SQLSTATE error)

$mysqli::warning_count

mysqli_warning_count

N/A

根据数据库链接,返回最后一次数据库查询内警告的数量

Methods

mysqli::autocommit

mysqli_autocommit

N/A

打开或关闭数据库的自动提交(auto-committing)功能

mysqli::change_user

mysqli_change_user

N/A

更改指定数据库连接所使用的用户

mysqli::character_set_name, mysqli::client_encoding

mysqli_character_set_name

mysqli_client_encoding

返回数据库连接的默认字符集

mysqli::close

mysqli_close

N/A

关闭先前打开的数据库连接

mysqli::commit

mysqli_commit

N/A

提交当前的数据库事务

mysqli::__construct

mysqli_connect

N/A

打开新连接到 MySQL 服务器[注意:静态方法]

mysqli::debug

mysqli_debug

N/A

执行调试操作

mysqli::dump_debug_info

mysqli_dump_debug_info

N/A

将调试信息转储到日志中

mysqli::get_charset

mysqli_get_charset

N/A

返回包含字符集信息的对象

mysqli::get_connection_stats

mysqli_get_connection_stats

N/A

返回客户端连接的统计信息。仅可用于 mysqlnd

mysqli::get_client_info

mysqli_get_client_info

N/A

返回 MySQL 客户端版本的字符串信息

mysqli::get_client_stats

mysqli_get_client_stats

N/A

返回每个客户端进程的统计信息。 仅可用于 mysqlnd

mysqli::get_cache_stats

mysqli_get_cache_stats

N/A

返回客户端的 Zval 缓存统计信息。 仅可用于 mysqlnd

mysqli::get_server_info

mysqli_get_server_info

N/A

返回 MySQLi 连接上的 MySQL 服务器的版本字符串

mysqli::get_warnings

mysqli_get_warnings

N/A

文档暂缺

mysqli::init

mysqli_init

N/A

初始化 MySQLi,返回资源类型的值,可供 mysqli_real_connect 使用。 [不要在对象上调用,它返回了 $mysqli 对象]

mysqli::kill

mysqli_kill

N/A

请求服务器杀死一个 MySQL 线程

mysqli::more_results

mysqli_more_results

N/A

检查多语句查询内是否还有更多查询结果

mysqli::multi_query

mysqli_multi_query

N/A

在数据库内执行多语句查询

mysqli::next_result

mysqli_next_result

N/A

从 multi_query 中准备下一个结果集

mysqli::options

mysqli_options

mysqli_set_opt

设置选项

mysqli::ping

mysqli_ping

N/A

Ping 服务器链接,如果链接已经断开,尝试重连

mysqli::prepare

mysqli_prepare

N/A

准备(prepare)需要执行的 SQL 语句

mysqli::query

mysqli_query

N/A

在数据库内执行查询

mysqli::real_connect

mysqli_real_connect

N/A

打开一个 MySQL 服务端的连接

mysqli::real_escape_string, <span class="methodname">mysqli::escape_string

mysqli_real_escape_string

mysqli_escape_string

转义特殊字符,用于 SQL 语句,该转换会考虑连接中当前的字符集

mysqli::real_query

mysqli_real_query

N/A

执行 SQL 查询

mysqli::refresh

mysqli_refresh

N/A

刷新表或缓存,或重置复制(replication)服务器信息

mysqli::rollback

mysqli_rollback

N/A

回滚当前事务

mysqli::select_db

mysqli_select_db

N/A

为数据库查询设置默认数据库

mysqli::set_charset

mysqli_set_charset

N/A

设置默认的客户端字符集

mysqli::set_local_infile_default

mysqli_set_local_infile_default

N/A

清除用户设置的 load data local infile 命令的处理程序

mysqli::set_local_infile_handler

mysqli_set_local_infile_handler

N/A

设置 LOAD DATA LOCAL INFILE 命令执行的回调函数

mysqli::ssl_set

mysqli_ssl_set

N/A

使用 SSL 建立安全连接

mysqli::stat

mysqli_stat

N/A

获取当前系统状态

mysqli::stmt_init

mysqli_stmt_init

N/A

初始化语句并且返回供 mysqli_stmt_prepare 使用的对象

mysqli::store_result

mysqli_store_result

N/A

传输最后一个查询的结果集

mysqli::thread_id

mysqli_thread_id

N/A

返回当前连接的线程ID

mysqli::thread_safe

mysqli_thread_safe

N/A

返回是否设定了线程安全

mysqli::use_result

mysqli_use_result

N/A

初始化一个结果集的取回

mysqli_stmt 的方法概述

MySQL_STMT

面向对象接口

面向过程接口

别名 (勿使用)

描述

属性

$mysqli_stmt::affected_rows

mysqli_stmt_affected_rows

N/A

返回受上次执行语句影响的总行数:修改、删除或插入

$mysqli_stmt::errno

mysqli_stmt_errno

N/A

返回最近一次语句调用的错误代码

$mysqli_stmt::error

mysqli_stmt_error

N/A

返回最后一条语句错误的字符串描述

$mysqli_stmt::field_count

mysqli_stmt_field_count

N/A

返回语句内的字段数量 - 文档暂缺

$mysqli_stmt::insert_id

mysqli_stmt_insert_id

N/A

获取上次 INSERT 操作生成的ID

$mysqli_stmt::num_rows

mysqli_stmt_num_rows

N/A

返回语句结果集中的行数

$mysqli_stmt::param_count

mysqli_stmt_param_count

mysqli_param_count

返回语句中参数的数量

$mysqli_stmt::sqlstate

mysqli_stmt_sqlstate

N/A

返回上次执行 SQL 语句的 SQLSTATE 错误代码

方法

mysqli_stmt::attr_get

mysqli_stmt_attr_get

N/A

用于获取语句属性的当前值

mysqli_stmt::attr_set

mysqli_stmt_attr_set

N/A

用于修改 prepared 语句的行为

mysqli_stmt::bind_param

mysqli_stmt_bind_param

mysqli_bind_param

绑定变量参数到 prepared 语句

mysqli_stmt::bind_result

mysqli_stmt_bind_result

mysqli_bind_result

绑定变量参数到 prepared 语句,用于结果存储

mysqli_stmt::close

mysqli_stmt_close

N/A

关闭 prepared 语句

mysqli_stmt::data_seek

mysqli_stmt_data_seek

N/A

定位到结果集中的任意行

mysqli_stmt::execute

mysqli_stmt_execute

mysqli_execute

执行 prepared 查询

mysqli_stmt::fetch

mysqli_stmt_fetch

mysqli_fetch

获取 prepared 语句中的结果,到指定变量中

mysqli_stmt::free_result

mysqli_stmt_free_result

N/A

释放给定语句处理存储的结果集所占内存

mysqli_stmt::get_result

mysqli_stmt_get_result

N/A

获取 prepared 语句中的结果。 仅可用于 mysqlnd

mysqli_stmt::get_warnings

mysqli_stmt_get_warnings

N/A

暂无文档

mysqli_stmt::more_results

mysqli_stmt_more_results

N/A

检查多语句查询中是否还有更多结果

mysqli_stmt::next_result

mysqli_stmt_next_result

N/A

读取多语句查询中下一条结果

mysqli_stmt::num_rows

mysqli_stmt_num_rows

N/A

参见 $mysqli_stmt::num_rows 中的属性

mysqli_stmt::prepare

mysqli_stmt_prepare

N/A

准备执行 SQL 语句

mysqli_stmt::reset

mysqli_stmt_reset

N/A

重置 prepare 语句

mysqli_stmt::result_metadata

mysqli_stmt_result_metadata

mysqli_get_metadata

返回 prepare 语句结果集内的元数据

mysqli_stmt::send_long_data

mysqli_stmt_send_long_data

mysqli_send_long_data

以块形式发送数据

mysqli_stmt::store_result

mysqli_stmt_store_result

N/A

从 prepare 语句中传输储存结果集

mysqli_result 方法概述

mysqli_result

面向对象接口

面向过程接口

别名 (勿使用)

描述

属性

$mysqli_result::current_field

mysqli_field_tell

N/A

获取当前字段在结果集指针中的开始位置

$mysqli_result::field_count

mysqli_num_fields

N/A

获取结果中字段数量

$mysqli_result::lengths

mysqli_fetch_lengths

N/A

返回结果集中当前行的列长度

$mysqli_result::num_rows

mysqli_num_rows

N/A

获取结果中行的数量

方法

mysqli_result::data_seek

mysqli_data_seek

N/A

将结果中的结果指针调整到任意行

mysqli_result::fetch_all

mysqli_fetch_all

N/A

抓取所有的结果行并且以关联数据,数值索引数组,或者两者皆有的方式返回结果集。 仅可用于 mysqlnd

mysqli_result::fetch_array

mysqli_fetch_array

N/A

以一个关联数组,数值索引数组,或者两者皆有的方式抓取一行结果

mysqli_result::fetch_assoc

mysqli_fetch_assoc

N/A

以一个关联数组方式抓取一行结果

mysqli_result::fetch_field_direct

mysqli_fetch_field_direct

N/A

抓取一个单字段的元数据

mysqli_result::fetch_field

mysqli_fetch_field

N/A

返回结果集中的下一个字段

mysqli_result::fetch_fields

mysqli_fetch_fields

N/A

返回一个代表结果集字段的对象数组

mysqli_result::fetch_object

mysqli_fetch_object

N/A

以一个对象的方式返回一个结果集中的当前行

mysqli_result::fetch_row

mysqli_fetch_row

N/A

以一个枚举数组方式返回一行结果

mysqli_result::field_seek

mysqli_field_seek

N/A

设置结果指针到特定的字段开始位置

mysqli_result::free, mysqli_result::close, mysqli_result::free_result

mysqli_free_result

N/A

释放与一个结果集相关的内存

mysqli_driver 的方法概述

MySQL_Driver

面向对象接口

面向过程接口

别名 (勿使用)

描述

属性

N/A

方法

mysqli_driver::embedded_server_end

mysqli_embedded_server_end

N/A

文档暂缺

mysqli_driver::embedded_server_start

mysqli_embedded_server_start

N/A

文档暂缺

Note:

提供函数的别名,目的仅为向下兼容。不要在新项目中使用!

简介

代表PHP和Mysql数据库之间的一个连接。

类摘要

mysqli

class mysqli {

/* 属性 */

int$mysqli->affected_rows;

int$mysqli->connect_errno;

string$mysqli->connect_error;

int$errno;

array$mysqli->error_list;

string$mysqli->error;

int$mysqli->field_count;

string$mysqli->client_info;

int$mysqli->client_version;

string$mysqli->host_info;

string$mysqli->protocol_version;

string$mysqli->server_info;

int$mysqli->server_version;

string$mysqli->info;

mixed$mysqli->insert_id;

string$mysqli->sqlstate;

int$mysqli->thread_id;

int$mysqli->warning_count;

/* 方法 */

int <span class="methodname">mysqli_affected_rows ( <span class="methodparam">mysqli $link )

bool <span class="methodname">autocommit ( <span class="type">bool $mode )

public bool begin_transaction ([ <span class="methodparam">int $flags<span class="initializer"> = 0 [, <span class="methodparam">string $name ]] )

public bool change_user ( <span class="methodparam">string $user , string $password , <span class="type">string $database )

string <span class="methodname">character_set_name ( <span class="methodparam">void )

bool close ( void )

bool commit ( void )

int <span class="methodname">mysqli_connect_errno ( <span class="methodparam">void )

string <span class="methodname">mysqli_connect_error ( <span class="methodparam">void )

public void connect ([ <span class="methodparam">string $host<span class="initializer"> = ini_get("mysqli.default_host") [, string $username = ini_get("mysqli.default_user") [, <span class="methodparam">string $passwd<span class="initializer"> = ini_get("mysqli.default_pw") [, string $dbname = "" [, <span class="methodparam">int $port<span class="initializer"> = ini_get("mysqli.default_port") [, string $socket = ini_get("mysqli.default_socket") ]]]]]] )

public bool debug ( <span class="type">string $message )

bool <span class="methodname">dump_debug_info ( <span class="methodparam">void )

int <span class="methodname">mysqli_errno ( <span class="methodparam">mysqli $link )

array <span class="methodname">mysqli_error_list ( <span class="methodparam">mysqli $link )

string <span class="methodname">mysqli_error ( <span class="methodparam">mysqli $link )

int <span class="methodname">mysqli_field_count ( <span class="methodparam">mysqli $link )

public object get_charset ( <span class="methodparam">void )

string <span class="methodname">get_client_info ( <span class="methodparam">void )

int <span class="methodname">mysqli_get_client_version ( <span class="methodparam">mysqli $link )

bool <span class="methodname">get_connection_stats ( <span class="methodparam">void )

string <span class="methodname">mysqli_get_host_info ( <span class="methodparam">mysqli $link )

int <span class="methodname">mysqli_get_proto_info ( <span class="methodparam">mysqli $link )

string <span class="methodname">mysqli_get_server_info ( <span class="methodparam">mysqli $link )

int <span class="methodname">mysqli_get_server_version ( <span class="methodparam">mysqli $link )

public <span class="type">mysqli_warning <span class="methodname">get_warnings ( <span class="methodparam">void )

string <span class="methodname">mysqli_info ( <span class="type">mysqli $link )

mysqli init ( void )

mixed <span class="methodname">mysqli_insert_id ( <span class="methodparam">mysqli $link )

bool kill ( int $processid )

bool <span class="methodname">more_results ( <span class="methodparam">void )

bool <span class="methodname">multi_query ( <span class="type">string $query )

bool <span class="methodname">next_result ( <span class="methodparam">void )

bool options ( int $option , mixed $value )

bool ping ( void )

public <span class="modifier">static int <span class="methodname">poll ( <span class="type">array &$read , <span class="methodparam">array &$error , array &$reject , <span class="type">int $sec [, <span class="methodparam">int $usec<span class="initializer"> = 0 ] )

mysqli_stmt <span class="methodname">prepare ( <span class="type">string $query )

mixed query ( string $query [, <span class="type">int $resultmode = MYSQLI_STORE_RESULT ] )

bool <span class="methodname">real_connect ([ <span class="methodparam">string $host [, string $username [, <span class="type">string $passwd [, <span class="methodparam">string $dbname [, int $port [, <span class="type">string $socket [, <span class="methodparam">int $flags ]]]]]]] )

string <span class="methodname">escape_string ( <span class="methodparam">string $escapestr )

bool <span class="methodname">real_query ( <span class="type">string $query )

public <span class="type">mysqli_result <span class="methodname">reap_async_query ( <span class="methodparam">void )

public bool refresh ( <span class="methodparam">int $options )

public bool release_savepoint ( <span class="methodparam">string $name )

bool rollback ( void )

public bool savepoint ( <span class="methodparam">string $name )

bool <span class="methodname">select_db ( <span class="type">string $dbname )

bool <span class="methodname">set_charset ( <span class="type">string $charset )

string <span class="methodname">mysqli_sqlstate ( <span class="methodparam">mysqli $link )

bool ssl_set ( string $key , <span class="type">string $cert , <span class="methodparam">string $ca , string $capath , <span class="type">string $cipher )

string stat ( void )

mysqli_stmt <span class="methodname">stmt_init ( <span class="methodparam">void )

mysqli_result <span class="methodname">store_result ([ <span class="methodparam">int $option ] )

int <span class="methodname">mysqli_thread_id ( <span class="methodparam">mysqli $link )

bool <span class="methodname">mysqli_thread_safe ( <span class="methodparam">void )

public <span class="type">mysqli_result <span class="methodname">use_result ( <span class="methodparam">void )

int <span class="methodname">mysqli_warning_count ( <span class="methodparam">mysqli $link )

}

mysqli::$affected_rows

mysqli_affected_rows

Gets the number of affected rows in a previous MySQL operation

说明

面向对象风格

int$mysqli->affected_rows;

过程化风格

int <span class="methodname">mysqli_affected_rows ( <span class="methodparam">mysqli $link )

Returns the number of rows affected by the last INSERT, UPDATE, REPLACE or DELETE query.

For SELECT statements <span class="function">mysqli_affected_rows works like <span class="function">mysqli_num_rows.

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

An integer greater than zero indicates the number of rows affected or retrieved. Zero indicates that no records were updated for an UPDATE statement, no rows matched the WHERE clause in the query or that no query has yet been executed. -1 indicates that the query returned an error.

Note:

If the number of affected rows is greater than the maximum integer value(PHP_INT_MAX), the number of affected rows will be returned as a string.

范例

示例 #1 $mysqli->affected_rows example

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* Insert rows */
$mysqli->query("CREATE TABLE Language SELECT * from CountryLanguage");
printf("Affected rows (INSERT): %d\n", $mysqli->affected_rows);

$mysqli->query("ALTER TABLE Language ADD Status int default 0");

/* update rows */
$mysqli->query("UPDATE Language SET Status=1 WHERE Percentage > 50");
printf("Affected rows (UPDATE): %d\n", $mysqli->affected_rows);

/* delete rows */
$mysqli->query("DELETE FROM Language WHERE Percentage < 50");
printf("Affected rows (DELETE): %d\n", $mysqli->affected_rows);

/* select all rows */
$result = $mysqli->query("SELECT CountryCode FROM Language");
printf("Affected rows (SELECT): %d\n", $mysqli->affected_rows);

$result->close();

/* Delete table Language */
$mysqli->query("DROP TABLE Language");

/* close connection */
$mysqli->close();
?>

过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

if (!$link) {
    printf("Can't connect to localhost. Error: %s\n", mysqli_connect_error());
    exit();
}

/* Insert rows */
mysqli_query($link, "CREATE TABLE Language SELECT * from CountryLanguage");
printf("Affected rows (INSERT): %d\n", mysqli_affected_rows($link));

mysqli_query($link, "ALTER TABLE Language ADD Status int default 0");

/* update rows */
mysqli_query($link, "UPDATE Language SET Status=1 WHERE Percentage > 50");
printf("Affected rows (UPDATE): %d\n", mysqli_affected_rows($link));

/* delete rows */
mysqli_query($link, "DELETE FROM Language WHERE Percentage < 50");
printf("Affected rows (DELETE): %d\n", mysqli_affected_rows($link));

/* select all rows */
$result = mysqli_query($link, "SELECT CountryCode FROM Language");
printf("Affected rows (SELECT): %d\n", mysqli_affected_rows($link));

mysqli_free_result($result);

/* Delete table Language */
mysqli_query($link, "DROP TABLE Language");

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Affected rows (INSERT): 984
Affected rows (UPDATE): 168
Affected rows (DELETE): 815
Affected rows (SELECT): 169

参见

  • mysqli_num_rows
  • mysqli_info

mysqli::autocommit

mysqli_autocommit

打开或关闭本次数据库连接的自动命令提交事务模式

说明

面向对象风格

bool <span class="methodname">mysqli::autocommit ( <span class="methodparam">bool $mode )

过程化风格

bool <span class="methodname">mysqli_autocommit ( <span class="methodparam">mysqli $link , bool $mode )

打开或关闭本次数据库连接的自动命令提交事务模式。

如需要确认当前连接的自动事务提交状态,可执行这个SQL请求SELECT @@autocommit.

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

mode
Whether to turn on auto-commit or not.

返回值

成功时返回 true, 或者在失败时返回 false

注释

Note:

这个方法不会在不支持事务处理的表单查询中生效,如MyISAM或 ISAM。

范例

示例 #1 mysqli::autocommit example

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* turn autocommit on */
$mysqli->autocommit(TRUE);

if ($result = $mysqli->query("SELECT @@autocommit")) {
    $row = $result->fetch_row();
    printf("Autocommit is %s\n", $row[0]);
    $result->free();
}

/* close connection */
$mysqli->close();
?>

过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

if (!$link) {
    printf("Can't connect to localhost. Error: %s\n", mysqli_connect_error());
    exit();
}

/* turn autocommit on */
mysqli_autocommit($link, TRUE);

if ($result = mysqli_query($link, "SELECT @@autocommit")) {
    $row = mysqli_fetch_row($result);
    printf("Autocommit is %s\n", $row[0]);
    mysqli_free_result($result);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Autocommit is 1

参见

  • mysqli_commit
  • mysqli_rollback

mysqli::begin_transaction

mysqli_begin_transaction

Starts a transaction

说明

面向对象风格

public bool mysqli::begin_transaction ([ <span class="methodparam">int $flags<span class="initializer"> = 0 [, <span class="methodparam">string $name ]] )

过程化风格:

bool <span class="methodname">mysqli_begin_transaction ( <span class="methodparam">mysqli $link [, int $flags<span class="initializer"> = 0 [, <span class="methodparam">string $name ]] )

Begins a transaction. Requires the InnoDB engine (it is enabled by default). For additional details about how MySQL transactions work, see » http://dev.mysql.com/doc/mysql/en/commit.html.

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

flags
Valid flags are:

  • MYSQLI_TRANS_START_READ_ONLY: Start the transaction as "START TRANSACTION READ ONLY". Requires MySQL 5.6 and above.

  • MYSQLI_TRANS_START_READ_WRITE: Start the transaction as "START TRANSACTION READ WRITE". Requires MySQL 5.6 and above.

  • MYSQLI_TRANS_START_WITH_CONSISTENT_SNAPSHOT: Start the transaction as "START TRANSACTION WITH CONSISTENT SNAPSHOT".

name
Savepoint name for the transaction.

返回值

成功时返回 true, 或者在失败时返回 false

注释

Note:

This function does not work with non transactional table types (like MyISAM or ISAM).

范例

示例 #1 mysqli::begin_transaction example

面向对象风格

<?php

/* Tell mysqli to throw an exception if an error occurs */
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* The table engine has to support transactions */
$mysqli->query("CREATE TABLE IF NOT EXISTS language (
    Code text NOT NULL,
    Speakers int(11) NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");

/* Start transaction */
$mysqli->begin_transaction();

try {
    /* Insert some values */
    $mysqli->query("INSERT INTO language(Code, Speakers) VALUES ('DE', 42000123)");

    /* Try to insert invalid values */
    $language_code = 'FR';
    $native_speakers = 'Unknown';
    $stmt = $mysqli->prepare('INSERT INTO language(Code, Speakers) VALUES (?,?)');
    $stmt->bind_param('ss', $language_code, $native_speakers);
    $stmt->execute();

    /* If code reaches this point without errors then commit the data in the database */
    $mysqli->commit();
} catch (mysqli_sql_exception $exception) {
    $mysqli->rollback();

    throw $exception;
}

过程化风格

<?php

/* Tell mysqli to throw an exception if an error occurs */
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

$mysqli = mysqli_connect("localhost", "my_user", "my_password", "world");

/* The table engine has to support transactions */
mysqli_query($mysqli, "CREATE TABLE IF NOT EXISTS language (
    Code text NOT NULL,
    Speakers int(11) NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");

/* Start transaction */
mysqli_begin_transaction($mysqli);

try {
    /* Insert some values */
    mysqli_query($mysqli, "INSERT INTO language(Code, Speakers) VALUES ('DE', 42000123)");

    /* Try to insert invalid values */
    $language_code = 'FR';
    $native_speakers = 'Unknown';
    $stmt = mysqli_prepare($mysqli, 'INSERT INTO language(Code, Speakers) VALUES (?,?)');
    mysqli_stmt_bind_param($stmt, 'ss', $language_code, $native_speakers);
    mysqli_stmt_execute($stmt);

    /* If code reaches this point without errors then commit the data in the database */
    mysqli_commit($mysqli);
} catch (mysqli_sql_exception $exception) {
    mysqli_rollback($mysqli);

    throw $exception;
}

参见

  • mysqli_autocommit
  • mysqli_commit
  • mysqli_rollback

mysqli::change_user

mysqli_change_user

Changes the user of the specified database connection

说明

面向对象风格

public bool mysqli::change_user ( <span class="methodparam">string $user , string $password , <span class="type">string $database )

过程化风格

bool <span class="methodname">mysqli_change_user ( <span class="methodparam">mysqli $link , string $user , <span class="type">string $password , <span class="methodparam">string $database )

Changes the user of the specified database connection and sets the current database.

In order to successfully change users a valid username and password parameters must be provided and that user must have sufficient permissions to access the desired database. If for any reason authorization fails, the current user authentication will remain.

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

user
The MySQL user name.

password
The MySQL password.

database
The database to change to.

If desired, the null value may be passed resulting in only changing the user and not selecting a database. To select a database in this case use the mysqli_select_db function.

返回值

成功时返回 true, 或者在失败时返回 false

注释

Note:

Using this command will always cause the current database connection to behave as if was a completely new database connection, regardless of if the operation was completed successfully. This reset includes performing a rollback on any active transactions, closing all temporary tables, and unlocking all locked tables.

范例

示例 #1 mysqli::change_user example

面向对象风格

<?php

/* connect database test */
$mysqli = new mysqli("localhost", "my_user", "my_password", "test");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* Set Variable a */
$mysqli->query("SET @a:=1");

/* reset all and select a new database */
$mysqli->change_user("my_user", "my_password", "world");

if ($result = $mysqli->query("SELECT DATABASE()")) {
    $row = $result->fetch_row();
    printf("Default database: %s\n", $row[0]);
    $result->close();
}

if ($result = $mysqli->query("SELECT @a")) {
    $row = $result->fetch_row();
    if ($row[0] === NULL) {
        printf("Value of variable a is NULL\n");
    }
    $result->close();
}

/* close connection */
$mysqli->close();
?>

过程化风格

<?php
/* connect database test */
$link = mysqli_connect("localhost", "my_user", "my_password", "test");

/* check connection */
if (!$link) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* Set Variable a */
mysqli_query($link, "SET @a:=1");

/* reset all and select a new database */
mysqli_change_user($link, "my_user", "my_password", "world");

if ($result = mysqli_query($link, "SELECT DATABASE()")) {
    $row = mysqli_fetch_row($result);
    printf("Default database: %s\n", $row[0]);
    mysqli_free_result($result);
}

if ($result = mysqli_query($link, "SELECT @a")) {
    $row = mysqli_fetch_row($result);
    if ($row[0] === NULL) {
        printf("Value of variable a is NULL\n");
    }
    mysqli_free_result($result);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Default database: world
Value of variable a is NULL

参见

  • mysqli_connect
  • mysqli_select_db

mysqli::character_set_name

mysqli_character_set_name

返回当前数据库连接的默认字符编码

说明

面向对象风格

string <span class="methodname">mysqli::character_set_name ( <span class="methodparam">void )

过程化风格

string <span class="methodname">mysqli_character_set_name ( <span class="methodparam">mysqli $link )

返回当前数据库连接的默认字符编码。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

The default character set for the current connection

范例

示例 #1 mysqli::character_set_name example

面向对象风格

<?php
/* Open a connection */
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* Print current character set */
$charset = $mysqli->character_set_name();
printf ("Current character set is %s\n", $charset);

$mysqli->close();
?>

过程化风格

<?php
/* Open a connection */
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (!$link) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* Print current character set */
$charset = mysqli_character_set_name($link);
printf ("Current character set is %s\n",$charset);

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Current character set is latin1_swedish_ci

参见

  • mysqli_set_charset
  • mysqli_client_encoding
  • mysqli_real_escape_string

mysqli::close

mysqli_close

关闭先前打开的数据库连接

说明

面向对象风格

bool <span class="methodname">mysqli::close ( <span class="methodparam">void )

过程化风格

bool <span class="methodname">mysqli_close ( <span class="methodparam">mysqli $link )

关闭先前打开的数据库连接

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

成功时返回 true, 或者在失败时返回 false

范例

See mysqli_connect.

参见

  • mysqli::__construct
  • mysqli_init
  • mysqli_real_connect

mysqli::commit

mysqli_commit

提交一个事务

说明

面向对象风格

bool <span class="methodname">mysqli::commit ( <span class="methodparam">void )

过程化风格

bool <span class="methodname">mysqli_commit ( <span class="methodparam">mysqli $link )

提交数据库连接的当前事务

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 mysqli::commit example

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$mysqli->query("CREATE TABLE Language LIKE CountryLanguage");

/* set autocommit to off */
$mysqli->autocommit(FALSE);

/* Insert some values */
$mysqli->query("INSERT INTO Language VALUES ('DEU', 'Bavarian', 'F', 11.2)");
$mysqli->query("INSERT INTO Language VALUES ('DEU', 'Swabian', 'F', 9.4)");

/* commit transaction */
$mysqli->commit();

/* drop table */
$mysqli->query("DROP TABLE Language");

/* close connection */
$mysqli->close();
?>

过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "test");

/* check connection */
if (!$link) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* set autocommit to off */
mysqli_autocommit($link, FALSE);

mysqli_query($link, "CREATE TABLE Language LIKE CountryLanguage");

/* Insert some values */
mysqli_query($link, "INSERT INTO Language VALUES ('DEU', 'Bavarian', 'F', 11.2)");
mysqli_query($link, "INSERT INTO Language VALUES ('DEU', 'Swabian', 'F', 9.4)");

/* commit transaction */
mysqli_commit($link);

/* close connection */
mysqli_close($link);
?>

参见

  • mysqli_autocommit
  • mysqli_rollback

mysqli::$connect_errno

mysqli_connect_errno

Returns the error code from last connect call

说明

面向对象风格

int$mysqli->connect_errno;

过程化风格

int <span class="methodname">mysqli_connect_errno ( <span class="methodparam">void )

Returns the last error code number from the last call to <span class="function">mysqli_connect.

Note:

Client error message numbers are listed in the MySQL errmsg.h header file, server error message numbers are listed in mysqld_error.h. In the MySQL source distribution you can find a complete list of error messages and error numbers in the file Docs/mysqld_error.txt.

返回值

An error code value for the last call to <span class="function">mysqli_connect, if it failed. zero means no error occurred.

范例

示例 #1 $mysqli->connect_errno example

面向对象风格

<?php
$mysqli = @new mysqli('localhost', 'fake_user', 'my_password', 'my_db');

if ($mysqli->connect_errno) {
    die('Connect Error: ' . $mysqli->connect_errno);
}
?>

过程化风格

<?php
$link = @mysqli_connect('localhost', 'fake_user', 'my_password', 'my_db');

if (!$link) {
    die('Connect Error: ' . mysqli_connect_errno());
}
?>

以上例程会输出:

Connect Error: 1045

参见

  • mysqli_connect
  • mysqli_connect_error
  • mysqli_errno
  • mysqli_error
  • mysqli_sqlstate

mysqli::$connect_error

mysqli_connect_error

Returns a string description of the last connect error

说明

面向对象风格

string$mysqli->connect_error;

过程化风格

string <span class="methodname">mysqli_connect_error ( <span class="methodparam">void )

Returns the last error message string from the last call to <span class="function">mysqli_connect.

返回值

A string that describes the error. null is returned if no error occurred.

范例

示例 #1 $mysqli->connect_error example

面向对象风格

<?php
$mysqli = @new mysqli('localhost', 'fake_user', 'my_password', 'my_db');

// Works as of PHP 5.2.9 and 5.3.0.
if ($mysqli->connect_error) {
    die('Connect Error: ' . $mysqli->connect_error);
}
?>

过程化风格

<?php
$link = @mysqli_connect('localhost', 'fake_user', 'my_password', 'my_db');

if (!$link) {
    die('Connect Error: ' . mysqli_connect_error());
}
?>

以上例程会输出:

Connect Error: Access denied for user 'fake_user'@'localhost' (using password: YES)

注释

Warning

The mysqli->connect_error property only works properly as of PHP versions 5.2.9 and 5.3.0. Use the <span class="function">mysqli_connect_error function if compatibility with earlier PHP versions is required.

参见

  • mysqli_connect
  • mysqli_connect_errno
  • mysqli_errno
  • mysqli_error
  • mysqli_sqlstate

mysqli::__construct

mysqli::connect

mysqli_connect

Open a new connection to the MySQL server

说明

面向对象风格

public <span class="methodname">mysqli::__construct ([ <span class="methodparam">string $host<span class="initializer"> = ini_get("mysqli.default_host") [, string $username = ini_get("mysqli.default_user") [, <span class="methodparam">string $passwd<span class="initializer"> = ini_get("mysqli.default_pw") [, string $dbname = "" [, <span class="methodparam">int $port<span class="initializer"> = ini_get("mysqli.default_port") [, string $socket = ini_get("mysqli.default_socket") ]]]]]] )

public void mysqli::connect ([ <span class="methodparam">string $host<span class="initializer"> = ini_get("mysqli.default_host") [, string $username = ini_get("mysqli.default_user") [, <span class="methodparam">string $passwd<span class="initializer"> = ini_get("mysqli.default_pw") [, string $dbname = "" [, <span class="methodparam">int $port<span class="initializer"> = ini_get("mysqli.default_port") [, string $socket = ini_get("mysqli.default_socket") ]]]]]] )

过程化风格

mysqli<span class="type">false <span class="methodname">mysqli_connect ([ <span class="methodparam">string $host<span class="initializer"> = ini_get("mysqli.default_host") [, string $username = ini_get("mysqli.default_user") [, <span class="methodparam">string $passwd<span class="initializer"> = ini_get("mysqli.default_pw") [, string $dbname = "" [, <span class="methodparam">int $port<span class="initializer"> = ini_get("mysqli.default_port") [, string $socket = ini_get("mysqli.default_socket") ]]]]]] )

Opens a connection to the MySQL Server.

参数

host
Can be either a host name or an IP address. Passing the null value or the string "localhost" to this parameter, the local host is assumed. When possible, pipes will be used instead of the TCP/IP protocol.

Prepending host by p: opens a persistent connection. <span class="function">mysqli_change_user is automatically called on connections opened from the connection pool.

username
The MySQL user name.

passwd
If not provided or null, the MySQL server will attempt to authenticate the user against those user records which have no password only. This allows one username to be used with different permissions (depending on if a password is provided or not).

dbname
If provided will specify the default database to be used when performing queries.

port
Specifies the port number to attempt to connect to the MySQL server.

socket
Specifies the socket or named pipe that should be used.

Note:

Specifying the socket parameter will not explicitly determine the type of connection to be used when connecting to the MySQL server. How the connection is made to the MySQL database is determined by the host parameter.

返回值

Returns an object which represents the connection to a MySQL Server, 或者在失败时返回 false.

范例

示例 #1 mysqli::__construct example

面向对象风格

<?php
$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_db');

/*
 * This is the "official" OO way to do it,
 * BUT $connect_error was broken until PHP 5.2.9 and 5.3.0.
 */
if ($mysqli->connect_error) {
    die('Connect Error (' . $mysqli->connect_errno . ') '
            . $mysqli->connect_error);
}

/*
 * Use this instead of $connect_error if you need to ensure
 * compatibility with PHP versions prior to 5.2.9 and 5.3.0.
 */
if (mysqli_connect_error()) {
    die('Connect Error (' . mysqli_connect_errno() . ') '
            . mysqli_connect_error());
}

echo 'Success... ' . $mysqli->host_info . "\n";

$mysqli->close();
?>

面向对象风格 when extending mysqli class

<?php

class foo_mysqli extends mysqli {
    public function __construct($host, $user, $pass, $db) {
        parent::__construct($host, $user, $pass, $db);

        if (mysqli_connect_error()) {
            die('Connect Error (' . mysqli_connect_errno() . ') '
                    . mysqli_connect_error());
        }
    }
}

$db = new foo_mysqli('localhost', 'my_user', 'my_password', 'my_db');

echo 'Success... ' . $db->host_info . "\n";

$db->close();
?>

过程化风格

<?php
$link = mysqli_connect('localhost', 'my_user', 'my_password', 'my_db');

if (!$link) {
    die('Connect Error (' . mysqli_connect_errno() . ') '
            . mysqli_connect_error());
}

echo 'Success... ' . mysqli_get_host_info($link) . "\n";

mysqli_close($link);
?>

以上例程会输出:

Success... MySQL host info: localhost via TCP/IP

注释

Note:

MySQLnd 总是使用服务器的默认字符集。此字符集在连接握手/认证时发送,并被 mysqlnd 使用。

Libmysqlclient 使用 my.cnf 中的默认字符集或者由在调用 <span class="function">mysqli_init 之后,<span class="function">mysqli_real_connect 之前先调用 <span class="function">mysqli_options 来指定。

Note:

OO syntax only: If a connection fails an object is still returned. To check if the connection failed then use either the <span class="function">mysqli_connect_error function or the mysqli->connect_error property as in the preceding examples.

Note:

If it is necessary to set options, such as the connection timeout, mysqli_real_connect must be used instead.

Note:

Calling the constructor with no parameters is the same as calling mysqli_init.

Note:

Error "Can't create TCP/IP socket (10106)" usually means that the variables_order configure directive doesn't contain character E. On Windows, if the environment is not copied the SYSTEMROOT environment variable won't be available and PHP will have problems loading Winsock.

参见

  • mysqli_real_connect
  • mysqli_options
  • mysqli_connect_errno
  • mysqli_connect_error
  • mysqli_close

mysqli::debug

mysqli_debug

Performs debugging operations

说明

面向对象风格

public bool mysqli::debug ( <span class="methodparam">string $message )

过程化风格

bool <span class="methodname">mysqli_debug ( <span class="methodparam">string $message )

Performs debugging operations using the Fred Fish debugging library.

参数

message
A string representing the debugging operation to perform

返回值

Returns true.

注释

Note:

To use the mysqli_debug function you must compile the MySQL client library to support debugging.

范例

示例 #1 Generating a Trace File

<?php

/* Create a trace file in '/tmp/client.trace' on the local (client) machine: */
mysqli_debug("d:t:o,/tmp/client.trace");

?>

参见

  • mysqli_dump_debug_info
  • mysqli_report

mysqli::dump_debug_info

mysqli_dump_debug_info

将调试信息输出到日志

说明

面向对象风格

bool <span class="methodname">mysqli::dump_debug_info ( <span class="methodparam">void )

过程化风格

bool <span class="methodname">mysqli_dump_debug_info ( <span class="methodparam">mysqli $link )

这个函数设计用于超级权限用户执行将调试信息输出到连接相关的MySQL服务端日志

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

成功时返回 true, 或者在失败时返回 false

参见

  • mysqli_debug

mysqli::errno

mysqli_errno

返回最近函数调用的错误代码

说明

面向对象风格

mysqli

int$errno;

过程化风格

int <span class="methodname">mysqli_errno ( <span class="methodparam">mysqli $link )

返回最近的mysqli函数调用产生的错误代码.

客户端错误在Mysqlerrmsg.h头文件中列出, 服务端错误好在mysqld_error.h中列出. 在mysql源码分发包中的Docs/mysqld_error.txt你可以发现一个完整的错误消息和错误号.

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

最后一次调用产生的错误代码, 返回0代表没有错误发生.

范例

示例 #1 mysqli->errno example

面向对象风格

<?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->query("SET a=1")) {
    printf("Errorcode: %d\n", $mysqli->errno);
}

/* 关闭连接 */
$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_query($link, "SET a=1")) {
    printf("Errorcode: %d\n", mysqli_errno($link));
}

/* 关闭连接 */
mysqli_close($link);
?>

以上例程会输出:

Errorcode: 1193

参见

  • mysqli_connect_errno
  • mysqli_connect_error
  • mysqli_error
  • mysqli_sqlstate

mysqli::$error_list

mysqli_error_list

Returns a list of errors from the last command executed

说明

面向对象风格

array$mysqli->error_list;

过程化风格

array <span class="methodname">mysqli_error_list ( <span class="methodparam">mysqli $link )

Returns a array of errors for the most recent MySQLi function call that can succeed or fail.

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

A list of errors, each as an associative array containing the errno, error, and sqlstate.

范例

示例 #1 $mysqli->error_list example

面向对象风格

<?php
$mysqli = new mysqli("localhost", "nobody", "");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

if (!$mysqli->query("SET a=1")) {
    print_r($mysqli->error_list);
}

/* close connection */
$mysqli->close();
?>

过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

if (!mysqli_query($link, "SET a=1")) {
    print_r(mysqli_error_list($link));
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Array
(
    [0] => Array
        (
            [errno] => 1193
            [sqlstate] => HY000
            [error] => Unknown system variable 'a'
        )

)

参见

  • mysqli_connect_errno
  • mysqli_connect_error
  • mysqli_error
  • mysqli_sqlstate

mysqli::$error

mysqli_error

Returns a string description of the last error

说明

面向对象风格

string$mysqli->error;

过程化风格

string <span class="methodname">mysqli_error ( <span class="methodparam">mysqli $link )

Returns the last error message for the most recent MySQLi function call that can succeed or fail.

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

A string that describes the error. An empty string if no error occurred.

范例

示例 #1 $mysqli->error example

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if ($mysqli->connect_errno) {
    printf("Connect failed: %s\n", $mysqli->connect_error);
    exit();
}

if (!$mysqli->query("SET a=1")) {
    printf("Error message: %s\n", $mysqli->error);
}

/* close connection */
$mysqli->close();
?>

过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

if (!mysqli_query($link, "SET a=1")) {
    printf("Error message: %s\n", mysqli_error($link));
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Error message: Unknown system variable 'a'

参见

  • mysqli_connect_errno
  • mysqli_connect_error
  • mysqli_errno
  • mysqli_sqlstate

mysqli::$field_count

mysqli_field_count

Returns the number of columns for the most recent query

说明

面向对象风格

int$mysqli->field_count;

过程化风格

int <span class="methodname">mysqli_field_count ( <span class="methodparam">mysqli $link )

Returns the number of columns for the most recent query on the connection represented by the link parameter. This function can be useful when using the <span class="function">mysqli_store_result function to determine if the query should have produced a non-empty result set or not without knowing the nature of the query.

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

An integer representing the number of fields in a result set.

范例

示例 #1 $mysqli->field_count example

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "test");

$mysqli->query( "DROP TABLE IF EXISTS friends");
$mysqli->query( "CREATE TABLE friends (id int, name varchar(20))");

$mysqli->query( "INSERT INTO friends VALUES (1,'Hartmut'), (2, 'Ulf')");


$mysqli->real_query("SELECT * FROM friends");

if ($mysqli->field_count) {
    /* this was a select/show or describe query */
    $result = $mysqli->store_result();

    /* process resultset */
    $row = $result->fetch_row();

    /* free resultset */
    $result->close();
}

/* close connection */
$mysqli->close();
?>

过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "test");

mysqli_query($link, "DROP TABLE IF EXISTS friends");
mysqli_query($link, "CREATE TABLE friends (id int, name varchar(20))");

mysqli_query($link, "INSERT INTO friends VALUES (1,'Hartmut'), (2, 'Ulf')");

mysqli_real_query($link, "SELECT * FROM friends");

if (mysqli_field_count($link)) {
    /* this was a select/show or describe query */
    $result = mysqli_store_result($link);

    /* process resultset */
    $row = mysqli_fetch_row($result);

    /* free resultset */
    mysqli_free_result($result);
}

/* close connection */
mysqli_close($link);
?>

mysqli::get_charset

mysqli_get_charset

Returns a character set object

说明

面向对象风格

public object mysqli::get_charset ( <span class="methodparam">void )

过程化风格

object <span class="methodname">mysqli_get_charset ( <span class="methodparam">mysqli $link )

Returns a character set object providing several properties of the current active character set.

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

The function returns a character set object with the following properties:

charset
Character set name

collation
Collation name

dir
Directory the charset description was fetched from (?) or "" for built-in character sets

min_length
Minimum character length in bytes

max_length
Maximum character length in bytes

number
Internal character set number

state
Character set status (?)

范例

示例 #1 mysqli::get_charset example

面向对象风格

<?php
  $db = mysqli_init();
  $db->real_connect("localhost","root","","test");
  var_dump($db->get_charset());
?>

过程化风格

<?php
  $db = mysqli_init();
  mysqli_real_connect($db, "localhost","root","","test");
  var_dump(mysqli_get_charset($db));
?>

以上例程会输出:

object(stdClass)#2 (7) {
  ["charset"]=>
  string(6) "latin1"
  ["collation"]=>
  string(17) "latin1_swedish_ci"
  ["dir"]=>
  string(0) ""
  ["min_length"]=>
  int(1)
  ["max_length"]=>
  int(1)
  ["number"]=>
  int(8)
  ["state"]=>
  int(801)
}

参见

  • mysqli_character_set_name
  • mysqli_set_charset

mysqli::$client_info

mysqli::get_client_info

mysqli_get_client_info

获取 MySQL 客户端信息

说明

面向对象风格

string$mysqli->client_info;

string <span class="methodname">mysqli::get_client_info ( <span class="methodparam">void )

过程化风格

string <span class="methodname">mysqli_get_client_info ( <span class="methodparam">mysqli $link )

返回 MySQL 客户端库的版本信息。

返回值

返回 MySQL 客户端库的版本信息。

范例

示例 #1 mysqli_get_client_info

<?php

/* 获取客户端版本新的时候,
   无需建立到数据库的连接 */

printf("Client library version: %s\n", mysqli_get_client_info());
?>

参见

  • mysqli_get_client_version
  • mysqli_get_server_info
  • mysqli_get_server_version

mysqli_get_client_version

mysqli::$client_version

作为一个整数返回MySQL客户端的版本

说明

面向对象风格

int$mysqli->client_version;

过程化风格

int <span class="methodname">mysqli_get_client_version ( <span class="methodparam">mysqli $link )

作为一个整数返回客户端版本号.

返回值

一个表述MySQL客户端库版本的数字的格式: main_version*10000 + minor_version *100 + sub_version. 举个例子: 4.1.0 将返回 40100.

这有助于快速确定客户端库的版本来辨别是否有某些特性存在.

范例

示例 #1 mysqli_get_client_version

<?php

/* We don't need a connection to determine
   the version of mysql client library */

printf("Client library version: %d\n", mysqli_get_client_version());
?>

参见

  • mysqli_get_client_info
  • mysqli_get_server_info
  • mysqli_get_server_version

mysqli::get_connection_stats

mysqli_get_connection_stats

返回客户端连接的统计数据

说明

面向对象风格

bool <span class="methodname">mysqli::get_connection_stats ( <span class="methodparam">void )

过程化风格

array <span class="methodname">mysqli_get_connection_stats ( <span class="methodparam">mysqli $link )

返回客户端连接的统计数据, 仅可用于 mysqlnd。。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

返回一个数组,包含客户端连接的统计数据,否则 false

范例

示例 #1 A <span class="function">mysqli_get_connection_stats 例程

<?php
$link = mysqli_connect();
print_r(mysqli_get_connection_stats($link));
?>

以上例程的输出类似于:

Array
(
    [bytes_sent] => 43
    [bytes_received] => 80
    [packets_sent] => 1
    [packets_received] => 2
    [protocol_overhead_in] => 8
    [protocol_overhead_out] => 4
    [bytes_received_ok_packet] => 11
    [bytes_received_eof_packet] => 0
    [bytes_received_rset_header_packet] => 0
    [bytes_received_rset_field_meta_packet] => 0
    [bytes_received_rset_row_packet] => 0
    [bytes_received_prepare_response_packet] => 0
    [bytes_received_change_user_packet] => 0
    [packets_sent_command] => 0
    [packets_received_ok] => 1
    [packets_received_eof] => 0
    [packets_received_rset_header] => 0
    [packets_received_rset_field_meta] => 0
    [packets_received_rset_row] => 0
    [packets_received_prepare_response] => 0
    [packets_received_change_user] => 0
    [result_set_queries] => 0
    [non_result_set_queries] => 0
    [no_index_used] => 0
    [bad_index_used] => 0
    [slow_queries] => 0
    [buffered_sets] => 0
    [unbuffered_sets] => 0
    [ps_buffered_sets] => 0
    [ps_unbuffered_sets] => 0
    [flushed_normal_sets] => 0
    [flushed_ps_sets] => 0
    [ps_prepared_never_executed] => 0
    [ps_prepared_once_executed] => 0
    [rows_fetched_from_server_normal] => 0
    [rows_fetched_from_server_ps] => 0
    [rows_buffered_from_client_normal] => 0
    [rows_buffered_from_client_ps] => 0
    [rows_fetched_from_client_normal_buffered] => 0
    [rows_fetched_from_client_normal_unbuffered] => 0
    [rows_fetched_from_client_ps_buffered] => 0
    [rows_fetched_from_client_ps_unbuffered] => 0
    [rows_fetched_from_client_ps_cursor] => 0
    [rows_skipped_normal] => 0
    [rows_skipped_ps] => 0
    [copy_on_write_saved] => 0
    [copy_on_write_performed] => 0
    [command_buffer_too_small] => 0
    [connect_success] => 1
    [connect_failure] => 0
    [connection_reused] => 0
    [reconnect] => 0
    [pconnect_success] => 0
    [active_connections] => 1
    [active_persistent_connections] => 0
    [explicit_close] => 0
    [implicit_close] => 0
    [disconnect_close] => 0
    [in_middle_of_command_close] => 0
    [explicit_free_result] => 0
    [implicit_free_result] => 0
    [explicit_stmt_close] => 0
    [implicit_stmt_close] => 0
    [mem_emalloc_count] => 0
    [mem_emalloc_ammount] => 0
    [mem_ecalloc_count] => 0
    [mem_ecalloc_ammount] => 0
    [mem_erealloc_count] => 0
    [mem_erealloc_ammount] => 0
    [mem_efree_count] => 0
    [mem_malloc_count] => 0
    [mem_malloc_ammount] => 0
    [mem_calloc_count] => 0
    [mem_calloc_ammount] => 0
    [mem_realloc_count] => 0
    [mem_realloc_ammount] => 0
    [mem_free_count] => 0
    [proto_text_fetched_null] => 0
    [proto_text_fetched_bit] => 0
    [proto_text_fetched_tinyint] => 0
    [proto_text_fetched_short] => 0
    [proto_text_fetched_int24] => 0
    [proto_text_fetched_int] => 0
    [proto_text_fetched_bigint] => 0
    [proto_text_fetched_decimal] => 0
    [proto_text_fetched_float] => 0
    [proto_text_fetched_double] => 0
    [proto_text_fetched_date] => 0
    [proto_text_fetched_year] => 0
    [proto_text_fetched_time] => 0
    [proto_text_fetched_datetime] => 0
    [proto_text_fetched_timestamp] => 0
    [proto_text_fetched_string] => 0
    [proto_text_fetched_blob] => 0
    [proto_text_fetched_enum] => 0
    [proto_text_fetched_set] => 0
    [proto_text_fetched_geometry] => 0
    [proto_text_fetched_other] => 0
    [proto_binary_fetched_null] => 0
    [proto_binary_fetched_bit] => 0
    [proto_binary_fetched_tinyint] => 0
    [proto_binary_fetched_short] => 0
    [proto_binary_fetched_int24] => 0
    [proto_binary_fetched_int] => 0
    [proto_binary_fetched_bigint] => 0
    [proto_binary_fetched_decimal] => 0
    [proto_binary_fetched_float] => 0
    [proto_binary_fetched_double] => 0
    [proto_binary_fetched_date] => 0
    [proto_binary_fetched_year] => 0
    [proto_binary_fetched_time] => 0
    [proto_binary_fetched_datetime] => 0
    [proto_binary_fetched_timestamp] => 0
    [proto_binary_fetched_string] => 0
    [proto_binary_fetched_blob] => 0
    [proto_binary_fetched_enum] => 0
    [proto_binary_fetched_set] => 0
    [proto_binary_fetched_geometry] => 0
    [proto_binary_fetched_other] => 0
)

参见

mysqli::$host_info

mysqli_get_host_info

返回一个表述使用的连接类型的字符串

说明

面向对象风格

string$mysqli->host_info;

过程化风格

string <span class="methodname">mysqli_get_host_info ( <span class="methodparam">mysqli $link )

返回一个字符串,描述被link 参数所表述的连接 (包括服务器主机名).

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

一个特征字符串,表述服务器主机名和连接类型.

范例

示例 #1 $mysqli->host_info example

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* print host information */
printf("Host info: %s\n", $mysqli->host_info);

/* close connection */
$mysqli->close();
?>

过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* print host information */
printf("Host info: %s\n", mysqli_get_host_info($link));

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Host info: Localhost via UNIX socket

参见

  • mysqli_get_proto_info

mysqli::$protocol_version

mysqli_get_proto_info

返回MySQL使用的协议版本号

说明

面向对象风格

string$mysqli->protocol_version;

过程化风格

int <span class="methodname">mysqli_get_proto_info ( <span class="methodparam">mysqli $link )

返回一个整数,表述 被link参数所表述的连接 所使用的MySQL协议的版本号.

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

返回一个整数来表述协议的版本号.

范例

示例 #1 $mysqli->protocol_version example

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* print protocol version */
printf("Protocol version: %d\n", $mysqli->protocol_version);

/* close connection */
$mysqli->close();
?>

过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* print protocol version */
printf("Protocol version: %d\n", mysqli_get_proto_info($link));

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Protocol version: 10

参见

  • mysqli_get_host_info

mysqli::$server_info

mysqli_get_server_info

返回MySQL服务器的版本号

说明

面向对象风格

string$mysqli->server_info;

过程化风格

string <span class="methodname">mysqli_get_server_info ( <span class="methodparam">mysqli $link )

返回一个字符串,表述MySQLi扩展连接的MySQL服务器的版本号.

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

一个特征字符串,表述服务器的版本.

范例

示例 #1 $mysqli->server_info example

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* print server version */
printf("Server version: %s\n", $mysqli->server_info);

/* close connection */
$mysqli->close();
?>

过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* print server version */
printf("Server version: %s\n", mysqli_get_server_info($link));

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Server version: 4.1.2-alpha-debug

参见

  • mysqli_get_client_info
  • mysqli_get_client_version
  • mysqli_get_server_version

mysqli::$server_version

mysqli_get_server_version

作为一个整数返回MySQL服务器的版本

说明

面向对象风格

int$mysqli->server_version;

过程化风格

int <span class="methodname">mysqli_get_server_version ( <span class="methodparam">mysqli $link )

<span class="function">mysqli_get_server_version函数以整数的形式返回被连接的link参数所表述的服务器的版本.

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

一个整数表述的服务器版本.

版本号的格式是 main_version * 10000 + minor_version * 100 + sub_version (例如: 版本 4.1.0 是 40100).

范例

示例 #1 $mysqli->server_version example

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* print server version */
printf("Server version: %d\n", $mysqli->server_version);

/* close connection */
$mysqli->close();
?>

过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* print server version */
printf("Server version: %d\n", mysqli_get_server_version($link));

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Server version: 40102

参见

  • mysqli_get_client_info
  • mysqli_get_client_version
  • mysqli_get_server_info

mysqli::get_warnings

mysqli_get_warnings

Get result of SHOW WARNINGS

说明

面向对象风格

public <span class="type">mysqli_warning <span class="methodname">mysqli::get_warnings ( <span class="methodparam">void )

过程化风格

mysqli_warning <span class="methodname">mysqli_get_warnings ( <span class="methodparam">mysqli $link )

Warning

本函数还未编写文档,仅有参数列表。

mysqli::$info

mysqli_info

返回最近执行的 SQL 语句的信息

说明

面向对象风格

string$mysqli->info;

过程化风格

string <span class="methodname">mysqli_info ( <span class="type">mysqli $link )

mysqli_info 函数返回一个包含 最近执行的 SQL 语句信息的字符串。 下面有一些参考样例:

SQL 语句类型 返回结果字符串示例
INSERT INTO...SELECT... Records: 100 Duplicates: 0 Warnings: 0
INSERT INTO...VALUES (...),(...),(...) Records: 3 Duplicates: 0 Warnings: 0
LOAD DATA INFILE ... Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
ALTER TABLE ... Records: 3 Duplicates: 0 Warnings: 0
UPDATE ... Rows matched: 40 Changed: 40 Warnings: 0

Note:

如果所执行的 SQL 语句不是上面列出来的这几种类型的, <span class="function">mysqli_info 函数会返回一个空字符串。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

最近执行的 SQL 语句的相关信息。

范例

示例 #1 $mysqli->info 例程

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* 检查连接 */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$mysqli->query("CREATE TEMPORARY TABLE t1 LIKE City");

/* INSERT INTO .. SELECT */
$mysqli->query("INSERT INTO t1 SELECT * FROM City ORDER BY ID LIMIT 150");
printf("%s\n", $mysqli->info);

/* 关闭连接 */
$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();
}

mysqli_query($link, "CREATE TEMPORARY TABLE t1 LIKE City");

/* INSERT INTO .. SELECT */
mysqli_query($link, "INSERT INTO t1 SELECT * FROM City ORDER BY ID LIMIT 150");
printf("%s\n", mysqli_info($link));

/* 关闭连接 */
mysqli_close($link);
?>

以上例程会输出:

Records: 150  Duplicates: 0  Warnings: 0

参见

  • mysqli_affected_rows
  • mysqli_warning_count
  • mysqli_num_rows

mysqli::init

mysqli_init

初始化 MySQLi 并返回一个资源类型的值,这个值可以作为 mysqli_real_connect() 函数的传入参数

说明

面向对象风格

mysqli <span class="methodname">mysqli::init ( <span class="methodparam">void )

过程化风格

mysqli <span class="methodname">mysqli_init ( <span class="methodparam">void )

分配,或者初始化一个 MYSQL 对象,可以作为 <span class="function">mysqli_options 和 <span class="function">mysqli_real_connect 函数的传入参数使用。

Note:

在调用 mysqli_real_connect 函数之前调用其他的 mysqli 函数可能会调用失败。 (<span class="function">mysqli_options 函数除外)。

返回值

返回一个对象。

范例

参见 mysqli_real_connect.

参见

  • mysqli_options
  • mysqli_close
  • mysqli_real_connect
  • mysqli_connect

mysqli::$insert_id

mysqli_insert_id

返回最后一条插入语句产生的自增 ID

说明

面向对象风格

mixed$mysqli->insert_id;

过程化风格

mixed <span class="methodname">mysqli_insert_id ( <span class="methodparam">mysqli $link )

mysqli_insert_id 函数返回最后一个 SQL 语句(通常是 INSERT 语句) 所操作的表中设置为 AUTO_INCREMENT 的列的值。 如果最后一个 SQL 语句不是 INSERT 或者 UPDATE 语句, 或者所操作的表中没有设置为 AUTO_INCREMENT 的列, 返回值为 0。

Note:

如果在所执行的 INSERT 或者 UPDATE 语句中使用了数据库函数 LAST_INSERT_ID()。 有可能会影响 <span class="function">mysqli_insert_id 函数的返回值。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

最后一条 SQL(INSERT 或者 UPDATE)所操作的表中设置为 AUTO_INCREMENT 属性的列的值。 如果指定的连接上尚未执行 SQL 语句,或者最后一条 SQL 语句所操作的表中没有设为 AUTO_INCREMENT 的列,返回 0。

Note:

如果返回值超出了 php 允许的最大整数值, <span class="function">mysqli_insert_id 函数会以字符串形式返回这个值。

范例

示例 #1 $mysqli->insert_id 例程

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* 检查连接 */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$mysqli->query("CREATE TABLE myCity LIKE City");

$query = "INSERT INTO myCity VALUES (NULL, 'Stuttgart', 'DEU', 'Stuttgart', 617000)";
$mysqli->query($query);

printf ("New Record has id %d.\n", $mysqli->insert_id);

/* 删除表 */
$mysqli->query("DROP TABLE myCity");

/* 关闭连接 */
$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();
}

mysqli_query($link, "CREATE TABLE myCity LIKE City");

$query = "INSERT INTO myCity VALUES (NULL, 'Stuttgart', 'DEU', 'Stuttgart', 617000)";
mysqli_query($link, $query);

printf ("New Record has id %d.\n", mysqli_insert_id($link));

/* 删除表 */
mysqli_query($link, "DROP TABLE myCity");

/* 关闭连接 */
mysqli_close($link);
?>

以上例程会输出:

New Record has id 1.

mysqli::kill

mysqli_kill

让服务器杀掉一个 MySQL 线程

说明

面向对象风格

bool <span class="methodname">mysqli::kill ( <span class="type">int $processid )

过程化风格

bool <span class="methodname">mysqli_kill ( <span class="type">mysqli $link , <span class="methodparam">int $processid )

本函数可以用来让服务器杀掉 processid 参数指定的 线程 ID。数据库连接对应的线程 ID 可以通过 调用 <span class="function">mysqli_thread_id 函数得到。

如果仅仅想中止某个查询,请使用这个 SQL 语句: KILL QUERY processid

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 mysqli::kill 例程

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* 检查连接是否成功 */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* 获得连接对应的线程 ID */
$thread_id = $mysqli->thread_id;

/* 杀掉连接 */
$mysqli->kill($thread_id);

/* 下面的代码应该会发生错误 */
if (!$mysqli->query("CREATE TABLE myCity LIKE City")) {
    printf("Error: %s\n", $mysqli->error);
    exit;
}

/* 关闭连接 */
$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();
}

/* 获得连接对应的线程 ID */
$thread_id = mysqli_thread_id($link);

/* 杀掉连接 */
mysqli_kill($link, $thread_id);

/* 下面的代码应该会发生错误 */
if (!mysqli_query($link, "CREATE TABLE myCity LIKE City")) {
    printf("Error: %s\n", mysqli_error($link));
    exit;
}

/* 关闭连接 */
mysqli_close($link);
?>

以上例程会输出:

Error: MySQL server has gone away

参见

  • mysqli_thread_id

mysqli::more_results

mysqli_more_results

检查批量查询中是否还有查询结果

说明

面向对象风格

bool <span class="methodname">mysqli::more_results ( <span class="methodparam">void )

过程化风格

bool <span class="methodname">mysqli_more_results ( <span class="methodparam">mysqli $link )

检查上一次调用 mysqli_multi_query 函数之后, 是否还有更多的查询结果集。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

如果上一次调用 mysqli_multi_query 函数之后, 还有更多的结果集可以读取,返回 true,否则返回 false

范例

参见 mysqli_multi_query

参见

  • mysqli_multi_query
  • mysqli_next_result
  • mysqli_store_result
  • mysqli_use_result

mysqli::multi_query

mysqli_multi_query

执行查询

说明

面向对象风格

bool <span class="methodname">mysqli::multi_query ( <span class="methodparam">string $query )

过程化风格

bool <span class="methodname">mysqli_multi_query ( <span class="methodparam">mysqli $link , string $query )

执行一个 SQL 语句,或者多个使用分号分隔的 SQL 语句。

要获得执行结果中的第一个结果集,请使用 <span class="function">mysqli_use_result 或 <span class="function">mysqli_store_result 函数。 要读取后续的结果集, 请使用 <span class="function">mysqli_more_results 和 <span class="function">mysqli_next_result 函数。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

query
查询语句。

查询语句中的数据一定要正确的进行 转义

返回值

如果第一个 SQL 语句就失败了,返回 false。 如果是批量执行 SQL 语句, 必须首先调用 mysqli_next_result 函数,才可以获取后续语句的错误信息。

范例

示例 #1 mysqli::multi_query 例程

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* 检查连接 */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query  = "SELECT CURRENT_USER();";
$query .= "SELECT Name FROM City ORDER BY ID LIMIT 20, 5";

/* 批量执行查询 */
if ($mysqli->multi_query($query)) {
    do {
        /* store first result set */
        if ($result = $mysqli->store_result()) {
            while ($row = $result->fetch_row()) {
                printf("%s\n", $row[0]);
            }
            $result->free();
        }
        /* print divider */
        if ($mysqli->more_results()) {
            printf("-----------------\n");
        }
    } while ($mysqli->next_result());
}

/* 关闭连接 */
$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();
}

$query  = "SELECT CURRENT_USER();";
$query .= "SELECT Name FROM City ORDER BY ID LIMIT 20, 5";

/* 批量执行查询 */
if (mysqli_multi_query($link, $query)) {
    do {
        /* store first result set */
        if ($result = mysqli_store_result($link)) {
            while ($row = mysqli_fetch_row($result)) {
                printf("%s\n", $row[0]);
            }
            mysqli_free_result($result);
        }
        /* print divider */
        if (mysqli_more_results($link)) {
            printf("-----------------\n");
        }
    } while (mysqli_next_result($link));
}

/* 关闭连接 */
mysqli_close($link);
?>

以上例程的输出类似于:

my_user@localhost
-----------------
Amersfoort
Maastricht
Dordrecht
Leiden
Haarlemmermeer

参见

  • mysqli_query
  • mysqli_use_result
  • mysqli_store_result
  • mysqli_next_result
  • mysqli_more_results

mysqli::next_result

mysqli_next_result

为读取 multi_query 执行之后的下一个结果集做准备

说明

面向对象风格

bool <span class="methodname">mysqli::next_result ( <span class="methodparam">void )

过程化风格

bool <span class="methodname">mysqli_next_result ( <span class="methodparam">mysqli $link )

mysqli_multi_query 函数执行之后, 为读取下一个结果集做准备, 然后可以使用 <span class="function">mysqli_store_result 或 <span class="function">mysqli_use_result 函数读取下一个结果集。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

成功时返回 true, 或者在失败时返回 false

范例

See mysqli_multi_query.

参见

  • mysqli_multi_query
  • mysqli_more_results
  • mysqli_store_result
  • mysqli_use_result

mysqli::options

mysqli_options

设置选项

说明

面向对象风格

bool <span class="methodname">mysqli::options ( <span class="methodparam">int $option , mixed $value )

过程化风格

bool <span class="methodname">mysqli_options ( <span class="methodparam">mysqli $link , int $option , mixed $value )

设置一个连接的扩展选项,这些选项可以改变这个连接的行为。

如果要对多个选项进行设置,可以多次调用此函数来。

mysqli_options 需要在 <span class="function">mysqli_init 函数之后、 <span class="function">mysqli_real_connect 函数之前被调用。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

option
要进行设置的选项,可以是下列中的某一项:

名称 描述
MYSQLI_OPT_CONNECT_TIMEOUT 连接超时设置,以秒为单位(在 Windows 平台上,PHP 5.3.1 之后才支持此选项)。
MYSQLI_OPT_LOCAL_INFILE 启用或禁用 LOAD LOCAL INFILE 语句
MYSQLI_INIT_COMMAND 成功建立 MySQL 连接之后要执行的 SQL 语句
MYSQLI_READ_DEFAULT_FILE 从指定的文件中读取选项,而不是使用 my.cnf 中的选项
MYSQLI_READ_DEFAULT_GROUP my.cnf 或者 MYSQL_READ_DEFAULT_FILE 指定的文件中 读取指定的组中的选项。
MYSQLI_SERVER_PUBLIC_KEY SHA-256 认证模式下,要使用的 RSA 公钥文件。
MYSQLI_OPT_NET_CMD_BUFFER_SIZE 内部命令/网络缓冲大小, 仅在 mysqlnd 驱动下有效。
MYSQLI_OPT_NET_READ_BUFFER_SIZE 以字节为单位,读取 MySQL 命令报文时候的块大小, 仅在 mysqlnd 驱动下有效。
MYSQLI_OPT_INT_AND_FLOAT_NATIVE 将整数和浮点数类型的列转换成 PHP 的数值类型, 仅在 mysqlnd 驱动下有效。
MYSQLI_OPT_SSL_VERIFY_SERVER_CERT

value
选项值。

返回值

成功时返回 true, 或者在失败时返回 false

更新日志

版本 说明
5.5.0 新增 MYSQLI_SERVER_PUBLIC_KEYMYSQLI_SERVER_PUBLIC_KEY 选项。
5.3.0 新增 MYSQLI_OPT_INT_AND_FLOAT_NATIVEMYSQLI_OPT_NET_CMD_BUFFER_SIZEMYSQLI_OPT_NET_READ_BUFFER_SIZEMYSQLI_OPT_SSL_VERIFY_SERVER_CERT 选项。

范例

参见 mysqli_real_connect

注释

Note:

MySQLnd 总是使用服务器的默认字符集。此字符集在连接握手/认证时发送,并被 mysqlnd 使用。

Libmysqlclient 使用 my.cnf 中的默认字符集或者由在调用 <span class="function">mysqli_init 之后,<span class="function">mysqli_real_connect 之前先调用 <span class="function">mysqli_options 来指定。

参见

  • mysqli_init
  • mysqli_real_connect

mysqli::ping

mysqli_ping

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

说明

面向对象风格

bool <span class="methodname">mysqli::ping ( <span class="methodparam">void )

过程化风格

bool <span class="methodname">mysqli_ping ( <span class="type">mysqli $link )

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

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

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

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #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!

mysqli::poll

mysqli_poll

轮询连接

说明

面向对象风格

public <span class="modifier">static int <span class="methodname">mysqli::poll ( <span class="type">array &$read , <span class="methodparam">array &$error , array &$reject , <span class="type">int $sec [, <span class="methodparam">int $usec<span class="initializer"> = 0 ] )

过程化风格

int <span class="methodname">mysqli_poll ( <span class="type">array &$read , <span class="methodparam">array &$error , array &$reject , <span class="type">int $sec [, <span class="methodparam">int $usec<span class="initializer"> = 0 ] )

轮询连接。 仅可用于 mysqlnd。 此方法是 static 的。

参数

read
要检测是否存在可以读取的结果集的连接的数组。

error
发生错误的,例如:SQL 语句执行失败或者已经断开的 连接的数组。

reject
没有可以读取的结果集的连接 的数组。

sec
秒为单位的最大等待时间,不可以为负数。

usec
微秒为单位的最大等待时间,不可以为负数。

返回值

成功执行则返回存在可以读取结果集的连接数量, 否则 false

范例

示例 #1 A mysqli_poll 例程

<?php
$link1 = mysqli_connect();
$link1->query("SELECT 'test'", MYSQLI_ASYNC);
$all_links = array($link1);
$processed = 0;
do {
    $links = $errors = $reject = array();
    foreach ($all_links as $link) {
        $links[] = $errors[] = $reject[] = $link;
    }
    if (!mysqli_poll($links, $errors, $reject, 1)) {
        continue;
    }
    foreach ($links as $link) {
        if ($result = $link->reap_async_query()) {
            print_r($result->fetch_row());
            if (is_object($result))
                mysqli_free_result($result);
        } else die(sprintf("MySQLi Error: %s", mysqli_error($link)));
        $processed++;
    }
} while ($processed < count($all_links));
?>

以上例程会输出:

Array
(
    [0] => test
)

参见

  • mysqli_query
  • mysqli_reap_async_query

mysqli::prepare

mysqli_prepare

准备执行一个 SQL 语句

说明

面向对象风格

mysqli_stmt <span class="methodname">mysqli::prepare ( <span class="methodparam">string $query )

过程化风格

mysqli_stmt <span class="methodname">mysqli_prepare ( <span class="methodparam">mysqli $link , string $query )

做好执行 SQL 语句的准备,返回一个语句句柄,可以对这个句柄进行后续的操作。 这里仅仅支持单一的 SQL 语句,不支持多 SQL 语句。

在执行语句之前,需要使用 <span class="function">mysqli_stmt_bind_param 函数 对占位符参数进行绑定。 同样,在获取结果之前,必须使用 <span class="function">mysqli_stmt_bind_result 函数对返回的列值进行绑定。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

query
SQL 语句。

Note:

不需要在语句末尾增加分号(;) 或者 \g 结束符。

SQL 语句中可以包含一个或者多个问号(?) 表示语句的参数。

Note:

SQL 语句中,仅允许在特定的位置出现问号参数占位符。 例如,在 INSERT 语句中的 VALUES() 子句中可以使用参数占位符,来表示对应列的值。 也可以在 WHERE 字句中使用参数来表示 要进行比较的值。

但是,并不是所有的地方都允许使用参数占位符, 例如对于表名、列名这样的 SQL 语句中的标识位置, 就不可以使用参数占位。 SELECT 语句中的列名就不可以使用参数。 另外,对于 = 这样的逻辑比较操作也不可以在两侧都使用参数, 否则服务器在解析 SQL 的时候就不知道该如何检测参数类型了。 也不可以在 NULL 条件中使用问号, 也就是说不可以写成:? IS NULL。 一般而言,参数也只能用在数据操作(DML)语句中, 不可以用在数据定义(DDL)语句中。

返回值

mysqli_prepare 返回一个 statement 对象,如果发生错误则返回 false

范例

示例 #1 mysqli::prepare 例程

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* 检查连接 */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$city = "Amersfoort";

/* 创建一个预编译 SQL 语句 */
if ($stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?")) {

    /* 对于参数占位符进行参数值绑定 */
    $stmt->bind_param("s", $city);

    /* 执行查询 */
    $stmt->execute();

    /* 将查询结果绑定到变量 */
    $stmt->bind_result($district);

    /* 获取查询结果值 */
    $stmt->fetch();

    printf("%s is in district %s\n", $city, $district);

    /* 关于语句对象 */
    $stmt->close();
}

/* 关闭连接 */
$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();
}

$city = "Amersfoort";

/* 创建一个预编译 SQL 语句 */
if ($stmt = mysqli_prepare($link, "SELECT District FROM City WHERE Name=?")) {

    /* 对于参数占位符进行参数值绑定 */
    mysqli_stmt_bind_param($stmt, "s", $city);

    /* 执行查询 */
    mysqli_stmt_execute($stmt);

    /* 将查询结果绑定到变量 */
    mysqli_stmt_bind_result($stmt, $district);

    /* 获取查询结果值 */
    mysqli_stmt_fetch($stmt);

    printf("%s is in district %s\n", $city, $district);

    /* 关闭语句句柄 */
    mysqli_stmt_close($stmt);
}

/* 关闭连接 */
mysqli_close($link);
?>

以上例程会输出:

Amersfoort is in district Utrecht

参见

  • mysqli_stmt_execute
  • mysqli_stmt_fetch
  • mysqli_stmt_bind_param
  • mysqli_stmt_bind_result
  • mysqli_stmt_close

mysqli::query

mysqli_query

对数据库执行一次查询

说明

面向对象风格

mixed <span class="methodname">mysqli::query ( <span class="methodparam">string $query [, int $resultmode = MYSQLI_STORE_RESULT ] )

过程化风格

mixed <span class="methodname">mysqli_query ( <span class="methodparam">mysqli $link , string $query [, <span class="type">int $resultmode = MYSQLI_STORE_RESULT ] )

Performs a query against the database.

For non-DML queries (not INSERT, UPDATE or DELETE), this function is similar to calling mysqli_real_query followed by either mysqli_use_result or mysqli_store_result.

Note:

In the case where you pass a statement to <span class="function">mysqli_query that is longer than max_allowed_packet of the server, the returned error codes are different depending on whether you are using MySQL Native Driver (mysqlnd) or MySQL Client Library (libmysqlclient). The behavior is as follows:

  • mysqlnd on Linux returns an error code of 1153. The error message means “got a packet bigger than max_allowed_packet bytes”.

  • mysqlnd on Windows returns an error code 2006. This error message means “server has gone away”.

  • libmysqlclient on all platforms returns an error code 2006. This error message means “server has gone away”.

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

query
The query string.

Data inside the query should be properly escaped.

resultmode
Either the constant MYSQLI_USE_RESULT or MYSQLI_STORE_RESULT depending on the desired behavior. By default, MYSQLI_STORE_RESULT is used.

If you use MYSQLI_USE_RESULT all subsequent calls will return error Commands out of sync unless you call <span class="function">mysqli_free_result

With MYSQLI_ASYNC (available with mysqlnd), it is possible to perform query asynchronously. mysqli_poll is then used to get results from such queries.

返回值

失败时返回 false,通过mysqli_query 成功执行SELECT, SHOW, DESCRIBEEXPLAIN查询会返回一个<span class="classname">mysqli_result 对象,其他查询则返回true

更新日志

版本 说明
5.3.0 Added the ability of async queries.

范例

示例 #1 mysqli::query example

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if ($mysqli->connect_errno) {
    printf("Connect failed: %s\n", $mysqli->connect_error);
    exit();
}

/* Create table doesn't return a resultset */
if ($mysqli->query("CREATE TEMPORARY TABLE myCity LIKE City") === TRUE) {
    printf("Table myCity successfully created.\n");
}

/* Select queries return a resultset */
if ($result = $mysqli->query("SELECT Name FROM City LIMIT 10")) {
    printf("Select returned %d rows.\n", $result->num_rows);

    /* free result set */
    $result->close();
}

/* If we have to retrieve large amount of data we use MYSQLI_USE_RESULT */
if ($result = $mysqli->query("SELECT * FROM City", MYSQLI_USE_RESULT)) {

    /* Note, that we can't execute any functions which interact with the
       server until result set was closed. All calls will return an
       'out of sync' error */
    if (!$mysqli->query("SET @a:='this will not work'")) {
        printf("Error: %s\n", $mysqli->error);
    }
    $result->close();
}

$mysqli->close();
?>

过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* Create table doesn't return a resultset */
if (mysqli_query($link, "CREATE TEMPORARY TABLE myCity LIKE City") === TRUE) {
    printf("Table myCity successfully created.\n");
}

/* Select queries return a resultset */
if ($result = mysqli_query($link, "SELECT Name FROM City LIMIT 10")) {
    printf("Select returned %d rows.\n", mysqli_num_rows($result));

    /* free result set */
    mysqli_free_result($result);
}

/* If we have to retrieve large amount of data we use MYSQLI_USE_RESULT */
if ($result = mysqli_query($link, "SELECT * FROM City", MYSQLI_USE_RESULT)) {

    /* Note, that we can't execute any functions which interact with the
       server until result set was closed. All calls will return an
       'out of sync' error */
    if (!mysqli_query($link, "SET @a:='this will not work'")) {
        printf("Error: %s\n", mysqli_error($link));
    }
    mysqli_free_result($result);
}

mysqli_close($link);
?>

以上例程会输出:

Table myCity successfully created.
Select returned 10 rows.
Error: Commands out of sync;  You can't run this command now

参见

  • mysqli_real_query
  • mysqli_multi_query
  • mysqli_free_result

mysqli::real_connect

mysqli_real_connect

建立一个 MySQL 服务器连接

说明

面向对象风格

bool <span class="methodname">mysqli::real_connect ([ <span class="methodparam">string $host [, string $username [, <span class="type">string $passwd [, <span class="methodparam">string $dbname [, int $port [, <span class="type">string $socket [, <span class="methodparam">int $flags ]]]]]]] )

过程化风格

bool <span class="methodname">mysqli_real_connect ( <span class="methodparam">mysqli $link [, string $host [, <span class="type">string $username [, <span class="methodparam">string $passwd [, string $dbname [, <span class="type">int $port [, <span class="methodparam">string $socket [, int $flags ]]]]]]] )

建立一个到 MySQL 服务器的链接。

mysqli_connect 的不同点:

  • mysqli_real_connect 需要一个有效的对象,这个对象由 <span class="function">mysqli_init 创建。

  • 可以使用 mysqli_options 设置各种连接设置。

  • 提供 flags 参数。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

host
可以使用域名、IP 地址。如果传送 null 或者字符串 "localhost" 那么会使用 通道替代 TCP/IP 连接本地服务器。

username
MySQL 登录用户名

passwd
如果设置 null,那么会使用没有密码验证的方式尝试登录。这样可以为一个用户 提供不同的权限,基于他是否提供了密码。

dbname
设置执行查询语句的默认数据库。

port
指定 MySQL 服务器的端口

socket
指定使用的 socket 或者命名通道。

Note:

指定 socket 参数并不能说明要采用何种方式连接数据库。 连接数据的方式由 host 设定。

flags
这里可以设置连接参数:

Name Description
MYSQLI_CLIENT_COMPRESS 使用压缩协议
MYSQLI_CLIENT_FOUND_ROWS 返回语句匹配的行数,而不是影响的行数
MYSQLI_CLIENT_IGNORE_SPACE 允许函数名称后有空格,这将使所有的函数名称成为保留字。
MYSQLI_CLIENT_INTERACTIVE 在关闭连接之前允许等待 interactive_timeout 秒, 他替代 wait_timeout 设定。
MYSQLI_CLIENT_SSL 使用 SSL 加密

Note:

从安全角度考虑,在 PHP 中不可以使用 MULTI_STATEMENT, 若要执行多查询语句,请使用 <span class="function">mysqli_multi_query。

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 mysqli::real_connect 例子

面向对象风格

<?php

$mysqli = mysqli_init();
if (!$mysqli) {
    die('mysqli_init failed');
}

if (!$mysqli->options(MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT = 0')) {
    die('Setting MYSQLI_INIT_COMMAND failed');
}

if (!$mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5)) {
    die('Setting MYSQLI_OPT_CONNECT_TIMEOUT failed');
}

if (!$mysqli->real_connect('localhost', 'my_user', 'my_password', 'my_db')) {
    die('Connect Error (' . mysqli_connect_errno() . ') '
            . mysqli_connect_error());
}

echo 'Success... ' . $mysqli->host_info . "\n";

$mysqli->close();
?>

面向对象风格 when extending mysqli class

<?php

class foo_mysqli extends mysqli {
    public function __construct($host, $user, $pass, $db) {
        parent::init();

        if (!parent::options(MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT = 0')) {
            die('Setting MYSQLI_INIT_COMMAND failed');
        }

        if (!parent::options(MYSQLI_OPT_CONNECT_TIMEOUT, 5)) {
            die('Setting MYSQLI_OPT_CONNECT_TIMEOUT failed');
        }

        if (!parent::real_connect($host, $user, $pass, $db)) {
            die('Connect Error (' . mysqli_connect_errno() . ') '
                    . mysqli_connect_error());
        }
    }
}

$db = new foo_mysqli('localhost', 'my_user', 'my_password', 'my_db');

echo 'Success... ' . $db->host_info . "\n";

$db->close();
?>

过程化风格

<?php

$link = mysqli_init();
if (!$link) {
    die('mysqli_init failed');
}

if (!mysqli_options($link, MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT = 0')) {
    die('Setting MYSQLI_INIT_COMMAND failed');
}

if (!mysqli_options($link, MYSQLI_OPT_CONNECT_TIMEOUT, 5)) {
    die('Setting MYSQLI_OPT_CONNECT_TIMEOUT failed');
}

if (!mysqli_real_connect($link, 'localhost', 'my_user', 'my_password', 'my_db')) {
    die('Connect Error (' . mysqli_connect_errno() . ') '
            . mysqli_connect_error());
}

echo 'Success... ' . mysqli_get_host_info($link) . "\n";

mysqli_close($link);
?>

以上例程会输出:

Success... MySQL host info: localhost via TCP/IP

注释

Note:

MySQLnd 总是使用服务器的默认字符集。此字符集在连接握手/认证时发送,并被 mysqlnd 使用。

Libmysqlclient 使用 my.cnf 中的默认字符集或者由在调用 <span class="function">mysqli_init 之后,<span class="function">mysqli_real_connect 之前先调用 <span class="function">mysqli_options 来指定。

参见

  • mysqli_connect
  • mysqli_init
  • mysqli_options
  • mysqli_ssl_set
  • mysqli_close

mysqli::real_escape_string

mysqli::escape_string

mysqli_real_escape_string

根据当前连接的字符集,对于 SQL 语句中的特殊字符进行转义

说明

面向对象风格

string <span class="methodname">mysqli::escape_string ( <span class="methodparam">string $escapestr )

string <span class="methodname">mysqli::real_escape_string ( <span class="methodparam">string $escapestr )

过程化风格

string <span class="methodname">mysqli_real_escape_string ( <span class="methodparam">mysqli $link , string $escapestr )

此函数用来对字符串中的特殊字符进行转义, 以使得这个字符串是一个合法的 SQL 语句。 传入的字符串会根据当前连接的字符集进行转义,得到一个编码后的合法的 SQL 语句。

Caution

在调用 mysqli_real_escape_string 函数之前, 必须先通过调用 <span class="function">mysqli_set_charset 函数或者在 MySQL 服务器端设置字符集。 更多信息请参考 字符集

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

escapestr
需要进行转义的字符串。

会被进行转义的字符包括: NUL (ASCII 0),\n,\r,\,'," 和 Control-Z.

返回值

转义后的字符串。

错误/异常

在无效的连接上调用此函数会返回 null 并发出一个 E_WARNING 级别的错误。

范例

示例 #1 mysqli::real_escape_string 例程

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* 检查连接 */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$mysqli->query("CREATE TEMPORARY TABLE myCity LIKE City");

$city = "'s Hertogenbosch";

/* 由于未对 $city 进行转义,此次查询会失败 */
if (!$mysqli->query("INSERT into myCity (Name) VALUES ('$city')")) {
    printf("Error: %s\n", $mysqli->sqlstate);
}

$city = $mysqli->real_escape_string($city);

/* 对 $city 进行转义之后,查询可以正常执行 */
if ($mysqli->query("INSERT into myCity (Name) VALUES ('$city')")) {
    printf("%d Row inserted.\n", $mysqli->affected_rows);
}

$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();
}

mysqli_query($link, "CREATE TEMPORARY TABLE myCity LIKE City");

$city = "'s Hertogenbosch";

/* 由于未对 $city 进行转义,此次查询会失败 */
if (!mysqli_query($link, "INSERT into myCity (Name) VALUES ('$city')")) {
    printf("Error: %s\n", mysqli_sqlstate($link));
}

$city = mysqli_real_escape_string($link, $city);

/* 对 $city 进行转义之后,查询可以正常执行 */
if (mysqli_query($link, "INSERT into myCity (Name) VALUES ('$city')")) {
    printf("%d Row inserted.\n", mysqli_affected_rows($link));
}

mysqli_close($link);
?>

以上例程会输出:

Error: 42000
1 Row inserted.

注释

Note:

如果你之前都是使用 <span class="function">mysql_real_escape_string 函数来转义 SQL 语句的, 那么需要注意的是 <span class="function">mysqli_real_escape_string 和 <span class="function">mysql_real_escape_string 两个函数的参数顺序不同。 <span class="function">mysqli_real_escape_string 中, link 是第一个参数, 而在 <span class="function">mysql_real_escape_string 函数中,要转义的字符串是第一个参数。

参见

  • mysqli_set_charset
  • mysqli_character_set_name

mysqli::real_query

mysqli_real_query

执行一个mysql查询

说明

面向对象风格

bool <span class="methodname">mysqli::real_query ( <span class="methodparam">string $query )

过程化风格

bool <span class="methodname">mysqli_real_query ( <span class="methodparam">mysqli $link , string $query )

执行一个单条数据库查询, 其结果可以使用<span class="function">mysqli_store_result或<span class="function">mysqli_use_result检索或存储.

为了确定给定的查询是否真的返回一个结果集, 可以查看<span class="function">mysqli_field_count.

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

query
查询字符串

查询中的数据可以进行属性转义.

返回值

成功时返回 true, 或者在失败时返回 false

参见

  • mysqli_query
  • mysqli_store_result
  • mysqli_use_result

mysqli::reap_async_query

mysqli_reap_async_query

获取异步查询的结果

说明

面向对象风格

public <span class="type">mysqli_result <span class="methodname">mysqli::reap_async_query ( <span class="methodparam">void )

过程化风格

mysqli_result <span class="methodname">mysqli_reap_async_query ( <span class="methodparam">mysqli $link )

获取异步查询的结果, 仅可用于 mysqlnd。。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

如果成功则返回 mysqli_result,否则返回 false

参见

  • mysqli_poll

mysqli::refresh

mysqli_refresh

刷新

说明

面向对象风格

public bool mysqli::refresh ( <span class="methodparam">int $options )

过程化风格

bool <span class="methodname">mysqli_refresh ( <span class="methodparam">resource $link , int $options )

刷新表或者缓存,或者重置主从服务器信息。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

options
使用 MySQLi 常量 中的 MYSQLI_REFRESH_* 常量作为刷新选项。

参见 MySQL 官方文档: » MySQL Refresh

返回值

成功返回 true,否则返回 false

参见

  • mysqli_poll

mysqli::release_savepoint

mysqli_release_savepoint

从当前事务的保存点中移除一个命名保存点

说明

面向对象风格 (method):

public bool mysqli::release_savepoint ( <span class="methodparam">string $name )

过程化风格:

bool <span class="methodname">mysqli_release_savepoint ( <span class="methodparam">mysqli $link , string $name )

Warning

本函数还未编写文档,仅有参数列表。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

name

返回值

成功时返回 true, 或者在失败时返回 false

参见

  • mysqli_rollback

mysqli::rollback

mysqli_rollback

回退当前事务

说明

面向对象风格

bool <span class="methodname">mysqli::rollback ( <span class="methodparam">void )

过程化风格

bool <span class="methodname">mysqli_rollback ( <span class="methodparam">mysqli $link )

回退当前数据库的事务。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 mysqli::rollback example

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* disable autocommit */
$mysqli->autocommit(FALSE);

$mysqli->query("CREATE TABLE myCity LIKE City");
$mysqli->query("ALTER TABLE myCity Type=InnoDB");
$mysqli->query("INSERT INTO myCity SELECT * FROM City LIMIT 50");

/* commit insert */
$mysqli->commit();

/* delete all rows */
$mysqli->query("DELETE FROM myCity");

if ($result = $mysqli->query("SELECT COUNT(*) FROM myCity")) {
    $row = $result->fetch_row();
    printf("%d rows in table myCity.\n", $row[0]);
    /* Free result */
    $result->close();
}

/* Rollback */
$mysqli->rollback();

if ($result = $mysqli->query("SELECT COUNT(*) FROM myCity")) {
    $row = $result->fetch_row();
    printf("%d rows in table myCity (after rollback).\n", $row[0]);
    /* Free result */
    $result->close();
}

/* Drop table myCity */
$mysqli->query("DROP TABLE myCity");

$mysqli->close();
?>

过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* disable autocommit */
mysqli_autocommit($link, FALSE);

mysqli_query($link, "CREATE TABLE myCity LIKE City");
mysqli_query($link, "ALTER TABLE myCity Type=InnoDB");
mysqli_query($link, "INSERT INTO myCity SELECT * FROM City LIMIT 50");

/* commit insert */
mysqli_commit($link);

/* delete all rows */
mysqli_query($link, "DELETE FROM myCity");

if ($result = mysqli_query($link, "SELECT COUNT(*) FROM myCity")) {
    $row = mysqli_fetch_row($result);
    printf("%d rows in table myCity.\n", $row[0]);
    /* Free result */
    mysqli_free_result($result);
}

/* Rollback */
mysqli_rollback($link);

if ($result = mysqli_query($link, "SELECT COUNT(*) FROM myCity")) {
    $row = mysqli_fetch_row($result);
    printf("%d rows in table myCity (after rollback).\n", $row[0]);
    /* Free result */
    mysqli_free_result($result);
}

/* Drop table myCity */
mysqli_query($link, "DROP TABLE myCity");

mysqli_close($link);
?>

以上例程会输出:

0 rows in table myCity.
50 rows in table myCity (after rollback).

参见

  • mysqli_commit
  • mysqli_autocommit

mysqli::savepoint

mysqli_savepoint

在当前事务中增加一个命名保存点

说明

面向对象风格 (method):

public bool mysqli::savepoint ( <span class="methodparam">string $name )

过程化风格:

bool <span class="methodname">mysqli_savepoint ( <span class="methodparam">mysqli $link , string $name )

Warning

本函数还未编写文档,仅有参数列表。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

name

返回值

成功时返回 true, 或者在失败时返回 false

参见

  • mysqli_commit

mysqli::select_db

mysqli_select_db

选择用于数据库查询的默认数据库

说明

面向对象风格

bool <span class="methodname">mysqli::select_db ( <span class="methodparam">string $dbname )

过程化风格

bool <span class="methodname">mysqli_select_db ( <span class="methodparam">mysqli $link , string $dbname )

针对本次数据库连接用于数据库查询的默认数据库。

Note:

本函数应该只被用在改变本次链接的数据库,你也能在<span class="function">mysqli_connect第四个参数确认默认数据库。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

dbname
数据库名称

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 mysqli::select_db example

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "test");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* return name of current default database */
if ($result = $mysqli->query("SELECT DATABASE()")) {
    $row = $result->fetch_row();
    printf("Default database is %s.\n", $row[0]);
    $result->close();
}

/* change db to world db */
$mysqli->select_db("world");

/* return name of current default database */
if ($result = $mysqli->query("SELECT DATABASE()")) {
    $row = $result->fetch_row();
    printf("Default database is %s.\n", $row[0]);
    $result->close();
}

$mysqli->close();
?>

过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "test");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* return name of current default database */
if ($result = mysqli_query($link, "SELECT DATABASE()")) {
    $row = mysqli_fetch_row($result);
    printf("Default database is %s.\n", $row[0]);
    mysqli_free_result($result);
}

/* change db to world db */
mysqli_select_db($link, "world");

/* return name of current default database */
if ($result = mysqli_query($link, "SELECT DATABASE()")) {
    $row = mysqli_fetch_row($result);
    printf("Default database is %s.\n", $row[0]);
    mysqli_free_result($result);
}

mysqli_close($link);
?>

以上例程会输出:

Default database is test.
Default database is world.

参见

  • mysqli_connect
  • mysqli_real_connect

mysqli::set_charset

mysqli_set_charset

设置默认字符编码

说明

面向对象风格

bool <span class="methodname">mysqli::set_charset ( <span class="methodparam">string $charset )

过程化风格

bool <span class="methodname">mysqli_set_charset ( <span class="methodparam">mysqli $link , string $charset )

设置在数据库间传输字符时所用的默认字符编码。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

charset
被设为默认的字符编码名。

返回值

成功时返回 true, 或者在失败时返回 false

注释

Note:

如果在Windows平台上使用该方法,需要4.1.11版或以上的MySQL客户端库,且MySQL版本为5.0.6以上。

Note:

这应该是首选的用于改变字符编码的方法,不建议使用<span class="function">mysqli_query执行SQL请求的SET NAMES ...(如 SET NAMES utf8)。 详见MySQL字符集的概念

范例

示例 #1 mysqli::set_charset example

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "test");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* change character set to utf8 */
if (!$mysqli->set_charset("utf8")) {
    printf("Error loading character set utf8: %s\n", $mysqli->error);
} else {
    printf("Current character set: %s\n", $mysqli->character_set_name());
}

$mysqli->close();
?>

过程化风格

<?php
$link = mysqli_connect('localhost', 'my_user', 'my_password', 'test');

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* change character set to utf8 */
if (!mysqli_set_charset($link, "utf8")) {
    printf("Error loading character set utf8: %s\n", mysqli_error($link));
} else {
    printf("Current character set: %s\n", mysqli_character_set_name($link));
}

mysqli_close($link);
?>

以上例程会输出:

Current character set: utf8

参见

mysqli::$sqlstate

mysqli_sqlstate

返回上一次 SQL 操作的 SQLSTATE 错误信息

说明

面向对象风格

string$mysqli->sqlstate;

过程化风格

string <span class="methodname">mysqli_sqlstate ( <span class="methodparam">mysqli $link )

返回一个包含 SQLSTATE 错误码的字符串,表示上一次 SQL 操作的错误。 错误码是由 5 个字符构成,'00000' 表示没有发生错误。 错误码是由 ANSI SQL 和 ODBC 定义的, 详细的清单请参见:» http://dev.mysql.com/doc/mysql/en/error-handling.html

Note:

需要注意的是,并不是所有的 MySQL 错误都映射到 SQLSTATE 了, 未映射的错误消息使用 HY000(综合错误)表示。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

返回一个包含 SQLSTATE 错误码的字符串,表示上一次 SQL 操作的错误。 错误码是由 5 个字符构成,'00000' 表示没有发生错误。

范例

示例 #1 $mysqli->sqlstate 例程

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* 检查连接 */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* City 表已经存在,所以我们会遇到一个错误 */
if (!$mysqli->query("CREATE TABLE City (ID INT, Name VARCHAR(30))")) {
    printf("Error - SQLSTATE %s.\n", $mysqli->sqlstate);
}

$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();
}

/* City 表已经存在,所以我们会遇到一个错误 */
if (!mysqli_query($link, "CREATE TABLE City (ID INT, Name VARCHAR(30))")) {
    printf("Error - SQLSTATE %s.\n", mysqli_sqlstate($link));
}

mysqli_close($link);
?>

以上例程会输出:

Error - SQLSTATE 42S01.

参见

  • mysqli_errno
  • mysqli_error

mysqli::ssl_set

mysqli_ssl_set

使用 SSL 建立到数据库之间的安全连接

说明

面向对象风格

bool <span class="methodname">mysqli::ssl_set ( <span class="methodparam">string $key , string $cert , <span class="type">string $ca , <span class="methodparam">string $capath , string $cipher )

过程化风格

bool <span class="methodname">mysqli_ssl_set ( <span class="methodparam">mysqli $link , string $key , string $cert , <span class="type">string $ca , <span class="methodparam">string $capath , string $cipher )

使用 SSL 建立到数据库之间的安全连接, 必须在调用 <span class="function">mysqli_real_connect 函数之前调用此函数。 除非启用 OpenSSL 支持,否则此函数无任何作用。

需要注意的是,在 PHP 5.3.3 之前的版本中, MySQL 原生驱动不支持建立 SSL 连接, 所以,在使用 MySQL 原生驱动的时候,调用此函数会产生错误。 从 PHP 5.3 开始,在 Windows 平台上,默认是启用 MySQL 原生驱动的。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

key
密钥文件的路径

cert
证书文件的路径

ca
签发机构的证书文件路径

capath
指向一个目录的路径, 该目录下存放的是受信任的 CA 机构证书 PEM 格式的文件。

cipher
SSL 加密允许使用的算法清单

任何未使用的 SSL 参数,可以设置为 null

返回值

此函数永远会返回 true。 如果 SSL 的设置有误,那么在调用 <span class="function">mysqli_real_connect 函数建立连接的时候才会报错。

参见

  • mysqli_options
  • mysqli_real_connect

mysqli::stat

mysqli_stat

获取当前系统状态信息

说明

面向对象风格

string <span class="methodname">mysqli::stat ( <span class="methodparam">void )

过程化风格

string <span class="methodname">mysqli_stat ( <span class="type">mysqli $link )

mysqli_stat 函数返回一个表示系统状态信息的字符串, 字符串中的内容和 'mysqladmin status' 命令的输出结果类似, 包含以秒为单位的运行时间、运行中的线程数、问题数、重新加载数以及打开的表数量等信息。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

成功则返回表示系统状态信息的字符串,失败则返回 false

范例

示例 #1 mysqli::stat 例程

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* 检查连接 */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

printf ("System status: %s\n", $mysqli->stat());

$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();
}

printf("System status: %s\n", mysqli_stat($link));

mysqli_close($link);
?>

以上例程会输出:

System status: Uptime: 272  Threads: 1  Questions: 5340  Slow queries: 0
Opens: 13  Flush tables: 1  Open tables: 0  Queries per second avg: 19.632
Memory in use: 8496K  Max memory used: 8560K

参见

  • mysqli_get_server_info

mysqli::stmt_init

mysqli_stmt_init

初始化一条语句并返回一个用于mysqli_stmt_prepare(调用)的对象

说明

面向对象风格

mysqli_stmt <span class="methodname">mysqli::stmt_init ( <span class="methodparam">void )

过程化风格

mysqli_stmt <span class="methodname">mysqli_stmt_init ( <span class="methodparam">mysqli $link )

分配并初始化一个语句对象用于<span class="function">mysqli_stmt_prepare.

Note:

任何其后调用的mysqli_stmt函数都会失败直到<span class="function">mysqli_stmt_prepare被调用.

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

Returns an object.

参见

  • mysqli_stmt_prepare

mysqli::store_result

mysqli_store_result

转移上一次查询返回的结果集

说明

面向对象风格

mysqli_result <span class="methodname">mysqli::store_result ([ <span class="methodparam">int $option ] )

过程化风格

mysqli_result <span class="methodname">mysqli_store_result ( <span class="methodparam">mysqli $link [, int $option ] )

迁移 link 参数所指定的连接上的上一次查询返回的结果集, 迁移之后的结果集可以 在 mysqli_data_seek 函数中使用。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

option
指定的选项,可以是下列中的某一值:

Name Description
MYSQLI_STORE_RESULT_COPY_DATA 将结果集从 mysqlnd 的内部缓冲区复制到 PHP 变量中。 默认情况下,mysqlnd 采取一种引用策略尽量避免在内容中复制多份同样的结果集。 例如,对于一个包含了很多行的结果集,每个行中的内容又不是很大,那么复制结果集的过程会导致内存使用率下降, 因为用来保存结果集数据的 PHP 变量可能提前被释放掉。 (此选项仅在使用 mysqlnd 驱动且 PHP 5.6.0 之后可用)。

返回值

成功则返回一个缓冲的结果集对象,失败则返回 false

Note:

如果上一查询并不产生结果集(例如,执行了一个 INSERT 语句), 那么 mysqli_store_result 会返回 false。 如果读取结果集失败了,也会返回 false。 如何区分是上面哪种情况导致此函数的调用返回了 false? 你可以通过下面的方法来检测: <span class="function">mysqli_error 返回了非空的字符串, <span class="function">mysqli_errno 返回了非零值, 或者 <span class="function">mysqli_field_count 返回了非零值, 都表示发生错误了。 还有一种可能的情况会导致此函数的调用返回 false:上一次查询 mysqli_query 本身是成功的, 但是由于返回的结果集太大,无法为其分配足够的内存来进行结果集转移。 如果 mysqli_field_count 函数返回了一个非零值,那么表示 SQL 语句产生了一个非空的结果集。

注释

Note:

执行查询之后, 使用 mysqli_free_result 函数来释放结果集所占用的内存, 是一个很有用的实战经验。 尤其是当使用 mysqli_store_result 函数来转移数量较大的结果集的时候, 释放结果集内存的操作尤为重要。

范例

See mysqli_multi_query.

参见

  • mysqli_real_query
  • mysqli_use_result

mysqli::$thread_id

mysqli_thread_id

返回当前连接的线程 ID

说明

面向对象风格

int$mysqli->thread_id;

过程化风格

int <span class="methodname">mysqli_thread_id ( <span class="methodparam">mysqli $link )

mysqli_thread_id 函数返回当前连接的线程 ID, 这个线程 ID 可以在 mysqli_kill 函数中使用。 如果 PHP 到数据库的连接中断了, 然后使用 <span class="function">mysqli_ping 函数重新建立连接的话, 新的连接的线程 ID 会发生改变。所以,仅在需要的时候,调用本函数获取连接的线程 ID。

Note:

线程 ID 是每次连接都重新分配的,也就是说它和连接是紧密相关的, 如果某个连接异常断开了,然后重新建立了到数据库的连接, 这个线程 ID 就不再是原来的那个了,它会发生变化。

可以通过执行 SQL 语句:KILL QUERY processid 来杀掉对应连接上正在执行的 SQL 语句。

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

返回当前连接的线程 ID

范例

示例 #1 $mysqli->thread_id 例程

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* 检查连接是否成功 */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* 获取连接的线程 ID */
$thread_id = $mysqli->thread_id;

/* 杀掉这个连接 */
$mysqli->kill($thread_id);

/* 这句代码应该会报错 */
if (!$mysqli->query("CREATE TABLE myCity LIKE City")) {
    printf("Error: %s\n", $mysqli->error);
    exit;
}

/* 关闭连接 */
$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();
}

/* 获取连接的线程 ID */
$thread_id = mysqli_thread_id($link);

/* 杀掉这个连接 */
mysqli_kill($link, $thread_id);

/* 这句代码应该会报错 */
if (!mysqli_query($link, "CREATE TABLE myCity LIKE City")) {
    printf("Error: %s\n", mysqli_error($link));
    exit;
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Error: MySQL server has gone away

参见

  • mysqli_kill

mysqli::thread_safe

mysqli_thread_safe

返回是否是线程安全的

说明

过程化风格

bool <span class="methodname">mysqli_thread_safe ( <span class="methodparam">void )

告知本数据库客户端库是否编译为线程安全的。 Tells whether the client library is compiled as thread-safe.

返回值

如果是的话,返回true,否则返回false

mysqli::use_result

mysqli_use_result

Initiate a result set retrieval

说明

面向对象风格

public <span class="type">mysqli_result <span class="methodname">mysqli::use_result ( <span class="methodparam">void )

过程化风格

mysqli_result <span class="methodname">mysqli_use_result ( <span class="methodparam">mysqli $link )

Used to initiate the retrieval of a result set from the last query executed using the mysqli_real_query function on the database connection.

Either this or the mysqli_store_result function must be called before the results of a query can be retrieved, and one or the other must be called to prevent the next query on that database connection from failing.

Note:

The mysqli_use_result function does not transfer the entire result set from the database and hence cannot be used functions such as <span class="function">mysqli_data_seek to move to a particular row within the set. To use this functionality, the result set must be stored using mysqli_store_result. One should not use mysqli_use_result if a lot of processing on the client side is performed, since this will tie up the server and prevent other threads from updating any tables from which the data is being fetched.

返回值

Returns an unbuffered result object or false if an error occurred.

范例

示例 #1 mysqli::use_result example

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query  = "SELECT CURRENT_USER();";
$query .= "SELECT Name FROM City ORDER BY ID LIMIT 20, 5";

/* execute multi query */
if ($mysqli->multi_query($query)) {
    do {
        /* store first result set */
        if ($result = $mysqli->use_result()) {
            while ($row = $result->fetch_row()) {
                printf("%s\n", $row[0]);
            }
            $result->close();
        }
        /* print divider */
        if ($mysqli->more_results()) {
            printf("-----------------\n");
        }
    } while ($mysqli->next_result());
}

/* close connection */
$mysqli->close();
?>

过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query  = "SELECT CURRENT_USER();";
$query .= "SELECT Name FROM City ORDER BY ID LIMIT 20, 5";

/* execute multi query */
if (mysqli_multi_query($link, $query)) {
    do {
        /* store first result set */
        if ($result = mysqli_use_result($link)) {
            while ($row = mysqli_fetch_row($result)) {
                printf("%s\n", $row[0]);
            }
            mysqli_free_result($result);
        }
        /* print divider */
        if (mysqli_more_results($link)) {
            printf("-----------------\n");
        }
    } while (mysqli_next_result($link));
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

my_user@localhost
-----------------
Amersfoort
Maastricht
Dordrecht
Leiden
Haarlemmermeer

参见

  • mysqli_real_query
  • mysqli_store_result

mysqli::$warning_count

mysqli_warning_count

Returns the number of warnings from the last query for the given link

说明

面向对象风格

int$mysqli->warning_count;

过程化风格

int <span class="methodname">mysqli_warning_count ( <span class="methodparam">mysqli $link )

Returns the number of warnings from the last query in the connection.

Note:

For retrieving warning messages you can use the SQL command SHOW WARNINGS [limit row_count].

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

返回值

Number of warnings or zero if there are no warnings.

范例

示例 #1 $mysqli->warning_count example

面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$mysqli->query("CREATE TABLE myCity LIKE City");

/* a remarkable city in Wales */
$query = "INSERT INTO myCity (CountryCode, Name) VALUES('GBR',
        'Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch')";

$mysqli->query($query);

if ($mysqli->warning_count) {
    if ($result = $mysqli->query("SHOW WARNINGS")) {
        $row = $result->fetch_row();
        printf("%s (%d): %s\n", $row[0], $row[1], $row[2]);
        $result->close();
    }
}

/* close connection */
$mysqli->close();
?>

过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

mysqli_query($link, "CREATE TABLE myCity LIKE City");

/* a remarkable long city name in Wales */
$query = "INSERT INTO myCity (CountryCode, Name) VALUES('GBR',
        'Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch')";

mysqli_query($link, $query);

if (mysqli_warning_count($link)) {
    if ($result = mysqli_query($link, "SHOW WARNINGS")) {
        $row = mysqli_fetch_row($result);
        printf("%s (%d): %s\n", $row[0], $row[1], $row[2]);
        mysqli_free_result($result);
    }
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Warning (1264): Data truncated for column 'Name' at row 1

参见

  • mysqli_errno
  • mysqli_error
  • mysqli_sqlstate

简介

代表一个预编译 SQL 语句。

类摘要

mysqli_stmt

class mysqli_stmt {

/* 属性 */

int$mysqli_stmt->affected_rows;

int$mysqli_stmt->errno;

array$mysqli_stmt->error_list;

string$mysqli_stmt->error;

int$mysqli_stmt->field_count;

int$mysqli_stmt->insert_id;

int$mysqli_stmt->num_rows;

int$mysqli_stmt->param_count;

string$mysqli_stmt->sqlstate;

/* 方法 */

int <span class="methodname">mysqli_stmt_affected_rows ( <span class="methodparam">mysqli_stmt $stmt )

public int <span class="methodname">attr_get ( <span class="type">int $attr )

public bool attr_set ( <span class="methodparam">int $attr , <span class="methodparam">int $mode )

public bool bind_param ( <span class="methodparam">string $types , mixed &$var , mixed &$vars )

public bool bind_result ( <span class="methodparam">mixed &$var , mixed &$vars )

public bool close ( <span class="methodparam">void )

public void data_seek ( <span class="methodparam">int $offset )

int <span class="methodname">mysqli_stmt_errno ( <span class="methodparam">mysqli_stmt $stmt )

array <span class="methodname">mysqli_stmt_error_list ( <span class="methodparam">mysqli_stmt $stmt )

string <span class="methodname">mysqli_stmt_error ( <span class="methodparam">mysqli_stmt $stmt )

public bool execute ( <span class="methodparam">void )

public bool fetch ( <span class="methodparam">void )

int <span class="methodname">mysqli_stmt_field_count ( <span class="methodparam">mysqli_stmt $stmt )

public void free_result ( <span class="methodparam">void )

public <span class="type">mysqli_result <span class="methodname">get_result ( <span class="methodparam">void )

public object get_warnings ( <span class="methodparam">void )

mixed <span class="methodname">mysqli_stmt_insert_id ( <span class="methodparam">mysqli_stmt $stmt )

public bool more_results ( <span class="methodparam">void )

public bool next_result ( <span class="methodparam">void )

public int <span class="methodname">num_rows ( <span class="methodparam">void )

int <span class="methodname">mysqli_stmt_param_count ( <span class="methodparam">mysqli_stmt $stmt )

public mixed prepare ( <span class="methodparam">string $query )

public bool reset ( <span class="methodparam">void )

public <span class="type">mysqli_result <span class="methodname">result_metadata ( <span class="methodparam">void )

public bool send_long_data ( <span class="methodparam">int $param_nr , string $data )

string <span class="methodname">mysqli_stmt_sqlstate ( <span class="methodparam">mysqli_stmt $stmt )

public bool store_result ( <span class="methodparam">void )

}

mysqli_stmt::$affected_rows

mysqli_stmt_affected_rows

Returns the total number of rows changed, deleted, or inserted by the last executed statement

说明

面向对象风格

int$mysqli_stmt->affected_rows;

过程化风格

int <span class="methodname">mysqli_stmt_affected_rows ( <span class="methodparam">mysqli_stmt $stmt )

Returns the number of rows affected by INSERT, UPDATE, or DELETE query.

This function only works with queries which update a table. In order to get the number of rows from a SELECT query, use <span class="function">mysqli_stmt_num_rows instead.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

返回值

An integer greater than zero indicates the number of rows affected or retrieved. Zero indicates that no records where updated for an UPDATE/DELETE statement, no rows matched the WHERE clause in the query or that no query has yet been executed. -1 indicates that the query has returned an error. NULL indicates an invalid argument was supplied to the function.

Note:

If the number of affected rows is greater than maximal PHP int value, the number of affected rows will be returned as a string value.

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* create temp table */
$mysqli->query("CREATE TEMPORARY TABLE myCountry LIKE Country");

$query = "INSERT INTO myCountry SELECT * FROM Country WHERE Code LIKE ?";

/* prepare statement */
if ($stmt = $mysqli->prepare($query)) {

    /* Bind variable for placeholder */
    $code = 'A%';
    $stmt->bind_param("s", $code);

    /* execute statement */
    $stmt->execute();

    printf("rows inserted: %d\n", $stmt->affected_rows);

    /* close statement */
    $stmt->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* create temp table */
mysqli_query($link, "CREATE TEMPORARY TABLE myCountry LIKE Country");

$query = "INSERT INTO myCountry SELECT * FROM Country WHERE Code LIKE ?";

/* prepare statement */
if ($stmt = mysqli_prepare($link, $query)) {

    /* Bind variable for placeholder */
    $code = 'A%';
    mysqli_stmt_bind_param($stmt, "s", $code);

    /* execute statement */
    mysqli_stmt_execute($stmt);

    printf("rows inserted: %d\n", mysqli_stmt_affected_rows($stmt));

    /* close statement */
    mysqli_stmt_close($stmt);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

rows inserted: 17

参见

  • mysqli_stmt_num_rows
  • mysqli_prepare

mysqli_stmt::attr_get

mysqli_stmt_attr_get

Used to get the current value of a statement attribute

说明

面向对象风格

public int <span class="methodname">mysqli_stmt::attr_get ( <span class="methodparam">int $attr )

过程化风格

int <span class="methodname">mysqli_stmt_attr_get ( <span class="methodparam">mysqli_stmt $stmt , int $attr )

Gets the current value of a statement attribute.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

attr
The attribute that you want to get.

返回值

Returns false if the attribute is not found, otherwise returns the value of the attribute.

mysqli_stmt::attr_set

mysqli_stmt_attr_set

Used to modify the behavior of a prepared statement

说明

面向对象风格

public bool mysqli_stmt::attr_set ( <span class="methodparam">int $attr , <span class="methodparam">int $mode )

过程化风格

bool <span class="methodname">mysqli_stmt_attr_set ( <span class="methodparam">mysqli_stmt $stmt , int $attr , int $mode )

Used to modify the behavior of a prepared statement. This function may be called multiple times to set several attributes.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

attr
The attribute that you want to set. It can have one of the following values:

Character Description
MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH Setting to true causes mysqli_stmt_store_result to update the metadata MYSQL_FIELD->max_length value.
MYSQLI_STMT_ATTR_CURSOR_TYPE Type of cursor to open for statement when mysqli_stmt_execute is invoked. mode can be MYSQLI_CURSOR_TYPE_NO_CURSOR (the default) or MYSQLI_CURSOR_TYPE_READ_ONLY.
MYSQLI_STMT_ATTR_PREFETCH_ROWS Number of rows to fetch from server at a time when using a cursor. mode can be in the range from 1 to the maximum value of unsigned long. The default is 1.

If you use the MYSQLI_STMT_ATTR_CURSOR_TYPE option with MYSQLI_CURSOR_TYPE_READ_ONLY, a cursor is opened for the statement when you invoke mysqli_stmt_execute. If there is already an open cursor from a previous <span class="function">mysqli_stmt_execute call, it closes the cursor before opening a new one. <span class="function">mysqli_stmt_reset also closes any open cursor before preparing the statement for re-execution. <span class="function">mysqli_stmt_free_result closes any open cursor.

If you open a cursor for a prepared statement, <span class="function">mysqli_stmt_store_result is unnecessary.

mode
The value to assign to the attribute.

参见

mysqli_stmt::bind_param

mysqli_stmt_bind_param

Binds variables to a prepared statement as parameters

说明

面向对象风格

public bool mysqli_stmt::bind_param ( <span class="methodparam">string $types , mixed &$var , mixed &$vars )

过程化风格

bool <span class="methodname">mysqli_stmt_bind_param ( <span class="methodparam">mysqli_stmt $stmt , <span class="type">string $types , <span class="methodparam">mixed &$var , mixed &$vars )

Bind variables for the parameter markers in the SQL statement that was passed to mysqli_prepare.

Note:

If data size of a variable exceeds max. allowed packet size (max_allowed_packet), you have to specify b in types and use mysqli_stmt_send_long_data to send the data in packets.

Note:

Care must be taken when using <span class="function">mysqli_stmt_bind_param in conjunction with call_user_func_array. Note that <span class="function">mysqli_stmt_bind_param requires parameters to be passed by reference, whereas <span class="function">call_user_func_array can accept as a parameter a list of variables that can represent references or values.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

types
A string that contains one or more characters which specify the types for the corresponding bind variables:

Character Description
i corresponding variable has type integer
d corresponding variable has type double
s corresponding variable has type string
b corresponding variable is a blob and will be sent in packets

var
vars
The number of variables and length of string types must match the parameters in the statement.

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'world');

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$stmt = $mysqli->prepare("INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
$stmt->bind_param('sssd', $code, $language, $official, $percent);

$code = 'DEU';
$language = 'Bavarian';
$official = "F";
$percent = 11.2;

/* execute prepared statement */
$stmt->execute();

printf("%d Row inserted.\n", $stmt->affected_rows);

/* close statement and connection */
$stmt->close();

/* Clean up table CountryLanguage */
$mysqli->query("DELETE FROM CountryLanguage WHERE Language='Bavarian'");
printf("%d Row deleted.\n", $mysqli->affected_rows);

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link = mysqli_connect('localhost', 'my_user', 'my_password', 'world');

/* check connection */
if (!$link) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent);

$code = 'DEU';
$language = 'Bavarian';
$official = "F";
$percent = 11.2;

/* execute prepared statement */
mysqli_stmt_execute($stmt);

printf("%d Row inserted.\n", mysqli_stmt_affected_rows($stmt));

/* close statement and connection */
mysqli_stmt_close($stmt);

/* Clean up table CountryLanguage */
mysqli_query($link, "DELETE FROM CountryLanguage WHERE Language='Bavarian'");
printf("%d Row deleted.\n", mysqli_affected_rows($link));

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

1 Row inserted.
1 Row deleted.

参见

  • mysqli_stmt_bind_result
  • mysqli_stmt_execute
  • mysqli_stmt_fetch
  • mysqli_prepare
  • mysqli_stmt_send_long_data
  • mysqli_stmt_errno
  • mysqli_stmt_error

mysqli_stmt::bind_result

mysqli_stmt_bind_result

Binds variables to a prepared statement for result storage

说明

面向对象风格

public bool mysqli_stmt::bind_result ( <span class="methodparam">mixed &$var , mixed &$vars )

过程化风格

bool <span class="methodname">mysqli_stmt_bind_result ( <span class="methodparam">mysqli_stmt $stmt , <span class="type">mixed &$var , <span class="methodparam">mixed &$vars )

Binds columns in the result set to variables.

When mysqli_stmt_fetch is called to fetch data, the MySQL client/server protocol places the data for the bound columns into the specified variables var/vars.

Note:

Note that all columns must be bound after <span class="function">mysqli_stmt_execute and prior to calling mysqli_stmt_fetch. Depending on column types bound variables can silently change to the corresponding PHP type.

A column can be bound or rebound at any time, even after a result set has been partially retrieved. The new binding takes effect the next time mysqli_stmt_fetch is called.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

var
The first variable to be bound.

vars
Further variables to be bound.

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* prepare statement */
if ($stmt = $mysqli->prepare("SELECT Code, Name FROM Country ORDER BY Name LIMIT 5")) {
    $stmt->execute();

    /* bind variables to prepared statement */
    $stmt->bind_result($col1, $col2);

    /* fetch values */
    while ($stmt->fetch()) {
        printf("%s %s\n", $col1, $col2);
    }

    /* close statement */
    $stmt->close();
}
/* close connection */
$mysqli->close();

?>

示例 #2 过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (!$link) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* prepare statement */
if ($stmt = mysqli_prepare($link, "SELECT Code, Name FROM Country ORDER BY Name LIMIT 5")) {
    mysqli_stmt_execute($stmt);

    /* bind variables to prepared statement */
    mysqli_stmt_bind_result($stmt, $col1, $col2);

    /* fetch values */
    while (mysqli_stmt_fetch($stmt)) {
        printf("%s %s\n", $col1, $col2);
    }

    /* close statement */
    mysqli_stmt_close($stmt);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

AFG Afghanistan
ALB Albania
DZA Algeria
ASM American Samoa
AND Andorra

参见

  • mysqli_stmt_get_result
  • mysqli_stmt_bind_param
  • mysqli_stmt_execute
  • mysqli_stmt_fetch
  • mysqli_prepare
  • mysqli_stmt_prepare
  • mysqli_stmt_init
  • mysqli_stmt_errno
  • mysqli_stmt_error

mysqli_stmt::close

mysqli_stmt_close

Closes a prepared statement

说明

面向对象风格

public bool mysqli_stmt::close ( <span class="methodparam">void )

过程化风格

bool <span class="methodname">mysqli_stmt_close ( <span class="methodparam">mysqli_stmt $stmt )

Closes a prepared statement. <span class="function">mysqli_stmt_close also deallocates the statement handle. If the current statement has pending or unread results, this function cancels them so that the next query can be executed.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

返回值

成功时返回 true, 或者在失败时返回 false

参见

  • mysqli_prepare

mysqli_stmt::__construct

Constructs a new mysqli_stmt object

说明

public <span class="methodname">mysqli_stmt::__construct ( <span class="methodparam">mysqli $link [, string $query ] )

This method constructs a new mysqli_stmt object.

参数

link
仅以过程化样式:由mysqli_connect 或 <span class="function">mysqli_init 返回的链接标识。

query
The query, as a string. If this parameter is omitted, then the constructor behaves identically to <span class="function">mysqli_stmt_init, if provided, then it behaves as per mysqli_prepare.

参见

  • mysqli_prepare
  • mysqli_stmt_init

mysqli_stmt::data_seek

mysqli_stmt_data_seek

Seeks to an arbitrary row in statement result set

说明

面向对象风格

public void mysqli_stmt::data_seek ( <span class="methodparam">int $offset )

过程化风格

void <span class="methodname">mysqli_stmt_data_seek ( <span class="methodparam">mysqli_stmt $stmt , int $offset )

Seeks to an arbitrary result pointer in the statement result set.

mysqli_stmt_store_result must be called prior to mysqli_stmt_data_seek.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

offset
Must be between zero and the total number of rows minus one (0.. <span class="function">mysqli_stmt_num_rows - 1).

返回值

没有返回值。

范例

示例 #1 面向对象风格

<?php
/* Open a connection */
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER BY Name";
if ($stmt = $mysqli->prepare($query)) {

    /* execute query */
    $stmt->execute();

    /* bind result variables */
    $stmt->bind_result($name, $code);

    /* store result */
    $stmt->store_result();

    /* seek to row no. 400 */
    $stmt->data_seek(399);

    /* fetch values */
    $stmt->fetch();

    printf ("City: %s  Countrycode: %s\n", $name, $code);

    /* close statement */
    $stmt->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
/* Open a connection */
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER BY Name";
if ($stmt = mysqli_prepare($link, $query)) {

    /* execute query */
    mysqli_stmt_execute($stmt);

    /* bind result variables */
    mysqli_stmt_bind_result($stmt, $name, $code);

    /* store result */
    mysqli_stmt_store_result($stmt);

    /* seek to row no. 400 */
    mysqli_stmt_data_seek($stmt, 399);

    /* fetch values */
    mysqli_stmt_fetch($stmt);

    printf ("City: %s  Countrycode: %s\n", $name, $code);

    /* close statement */
    mysqli_stmt_close($stmt);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

City: Benin City  Countrycode: NGA

参见

  • mysqli_prepare

mysqli_stmt::$errno

mysqli_stmt_errno

Returns the error code for the most recent statement call

说明

面向对象风格

int$mysqli_stmt->errno;

过程化风格

int <span class="methodname">mysqli_stmt_errno ( <span class="methodparam">mysqli_stmt $stmt )

Returns the error code for the most recently invoked statement function that can succeed or fail.

Client error message numbers are listed in the MySQL errmsg.h header file, server error message numbers are listed in mysqld_error.h. In the MySQL source distribution you can find a complete list of error messages and error numbers in the file Docs/mysqld_error.txt.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

返回值

An error code value. Zero means no error occurred.

范例

示例 #1 面向对象风格

<?php
/* Open a connection */
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$mysqli->query("CREATE TABLE myCountry LIKE Country");
$mysqli->query("INSERT INTO myCountry SELECT * FROM Country");


$query = "SELECT Name, Code FROM myCountry ORDER BY Name";
if ($stmt = $mysqli->prepare($query)) {

    /* drop table */
    $mysqli->query("DROP TABLE myCountry");

    /* execute query */
    $stmt->execute();

    printf("Error: %d.\n", $stmt->errno);

    /* close statement */
    $stmt->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
/* Open a connection */
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

mysqli_query($link, "CREATE TABLE myCountry LIKE Country");
mysqli_query($link, "INSERT INTO myCountry SELECT * FROM Country");


$query = "SELECT Name, Code FROM myCountry ORDER BY Name";
if ($stmt = mysqli_prepare($link, $query)) {

    /* drop table */
    mysqli_query($link, "DROP TABLE myCountry");

    /* execute query */
    mysqli_stmt_execute($stmt);

    printf("Error: %d.\n", mysqli_stmt_errno($stmt));

    /* close statement */
    mysqli_stmt_close($stmt);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Error: 1146.

参见

  • mysqli_stmt_error
  • mysqli_stmt_sqlstate

mysqli_stmt::$error_list

mysqli_stmt_error_list

Returns a list of errors from the last statement executed

说明

面向对象风格

array$mysqli_stmt->error_list;

过程化风格

array <span class="methodname">mysqli_stmt_error_list ( <span class="methodparam">mysqli_stmt $stmt )

Returns an array of errors for the most recently invoked statement function that can succeed or fail.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

返回值

A list of errors, each as an associative array containing the errno, error, and sqlstate.

范例

示例 #1 面向对象风格

<?php
/* Open a connection */
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$mysqli->query("CREATE TABLE myCountry LIKE Country");
$mysqli->query("INSERT INTO myCountry SELECT * FROM Country");


$query = "SELECT Name, Code FROM myCountry ORDER BY Name";
if ($stmt = $mysqli->prepare($query)) {

    /* drop table */
    $mysqli->query("DROP TABLE myCountry");

    /* execute query */
    $stmt->execute();

    echo "Error:\n";
    print_r($stmt->error_list);

    /* close statement */
    $stmt->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
/* Open a connection */
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

mysqli_query($link, "CREATE TABLE myCountry LIKE Country");
mysqli_query($link, "INSERT INTO myCountry SELECT * FROM Country");


$query = "SELECT Name, Code FROM myCountry ORDER BY Name";
if ($stmt = mysqli_prepare($link, $query)) {

    /* drop table */
    mysqli_query($link, "DROP TABLE myCountry");

    /* execute query */
    mysqli_stmt_execute($stmt);

    echo "Error:\n";
    print_r(mysql_stmt_error_list($stmt));

    /* close statement */
    mysqli_stmt_close($stmt);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Array
(
    [0] => Array
        (
            [errno] => 1146
            [sqlstate] => 42S02
            [error] => Table 'world.myCountry' doesn't exist
        )

)

参见

  • mysqli_stmt_error
  • mysqli_stmt_errno
  • mysqli_stmt_sqlstate

mysqli_stmt::$error

mysqli_stmt_error

Returns a string description for last statement error

说明

面向对象风格

string$mysqli_stmt->error;

过程化风格

string <span class="methodname">mysqli_stmt_error ( <span class="methodparam">mysqli_stmt $stmt )

Returns a string containing the error message for the most recently invoked statement function that can succeed or fail.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

返回值

A string that describes the error. An empty string if no error occurred.

范例

示例 #1 面向对象风格

<?php
/* Open a connection */
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$mysqli->query("CREATE TABLE myCountry LIKE Country");
$mysqli->query("INSERT INTO myCountry SELECT * FROM Country");


$query = "SELECT Name, Code FROM myCountry ORDER BY Name";
if ($stmt = $mysqli->prepare($query)) {

    /* drop table */
    $mysqli->query("DROP TABLE myCountry");

    /* execute query */
    $stmt->execute();

    printf("Error: %s.\n", $stmt->error);

    /* close statement */
    $stmt->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
/* Open a connection */
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

mysqli_query($link, "CREATE TABLE myCountry LIKE Country");
mysqli_query($link, "INSERT INTO myCountry SELECT * FROM Country");


$query = "SELECT Name, Code FROM myCountry ORDER BY Name";
if ($stmt = mysqli_prepare($link, $query)) {

    /* drop table */
    mysqli_query($link, "DROP TABLE myCountry");

    /* execute query */
    mysqli_stmt_execute($stmt);

    printf("Error: %s.\n", mysqli_stmt_error($stmt));

    /* close statement */
    mysqli_stmt_close($stmt);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Error: Table 'world.myCountry' doesn't exist.

参见

  • mysqli_stmt_errno
  • mysqli_stmt_sqlstate

mysqli_stmt::execute

mysqli_stmt_execute

Executes a prepared Query

说明

面向对象风格

public bool mysqli_stmt::execute ( <span class="methodparam">void )

过程化风格

bool <span class="methodname">mysqli_stmt_execute ( <span class="methodparam">mysqli_stmt $stmt )

Executes a query that has been previously prepared using the <span class="function">mysqli_prepare function. When executed any parameter markers which exist will automatically be replaced with the appropriate data.

If the statement is UPDATE, DELETE, or INSERT, the total number of affected rows can be determined by using the <span class="function">mysqli_stmt_affected_rows function. Likewise, if the query yields a result set the <span class="function">mysqli_stmt_fetch function is used.

Note:

When using mysqli_stmt_execute, the mysqli_stmt_fetch function must be used to fetch the data prior to performing any additional queries.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$mysqli->query("CREATE TABLE myCity LIKE City");

/* Prepare an insert statement */
$query = "INSERT INTO myCity (Name, CountryCode, District) VALUES (?,?,?)";
$stmt = $mysqli->prepare($query);

$stmt->bind_param("sss", $val1, $val2, $val3);

$val1 = 'Stuttgart';
$val2 = 'DEU';
$val3 = 'Baden-Wuerttemberg';

/* Execute the statement */
$stmt->execute();

$val1 = 'Bordeaux';
$val2 = 'FRA';
$val3 = 'Aquitaine';

/* Execute the statement */
$stmt->execute();

/* close statement */
$stmt->close();

/* retrieve all rows from myCity */
$query = "SELECT Name, CountryCode, District FROM myCity";
if ($result = $mysqli->query($query)) {
    while ($row = $result->fetch_row()) {
        printf("%s (%s,%s)\n", $row[0], $row[1], $row[2]);
    }
    /* free result set */
    $result->close();
}

/* remove table */
$mysqli->query("DROP TABLE myCity");

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

mysqli_query($link, "CREATE TABLE myCity LIKE City");

/* Prepare an insert statement */
$query = "INSERT INTO myCity (Name, CountryCode, District) VALUES (?,?,?)";
$stmt = mysqli_prepare($link, $query);

mysqli_stmt_bind_param($stmt, "sss", $val1, $val2, $val3);

$val1 = 'Stuttgart';
$val2 = 'DEU';
$val3 = 'Baden-Wuerttemberg';

/* Execute the statement */
mysqli_stmt_execute($stmt);

$val1 = 'Bordeaux';
$val2 = 'FRA';
$val3 = 'Aquitaine';

/* Execute the statement */
mysqli_stmt_execute($stmt);

/* close statement */
mysqli_stmt_close($stmt);

/* retrieve all rows from myCity */
$query = "SELECT Name, CountryCode, District FROM myCity";
if ($result = mysqli_query($link, $query)) {
    while ($row = mysqli_fetch_row($result)) {
        printf("%s (%s,%s)\n", $row[0], $row[1], $row[2]);
    }
    /* free result set */
    mysqli_free_result($result);
}

/* remove table */
mysqli_query($link, "DROP TABLE myCity");

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Stuttgart (DEU,Baden-Wuerttemberg)
Bordeaux (FRA,Aquitaine)

参见

  • mysqli_prepare
  • mysqli_stmt_bind_param
  • mysqli_stmt_get_result

mysqli_stmt::fetch

mysqli_stmt_fetch

Fetch results from a prepared statement into the bound variables

说明

面向对象风格

public bool mysqli_stmt::fetch ( <span class="methodparam">void )

过程化风格

bool <span class="methodname">mysqli_stmt_fetch ( <span class="methodparam">mysqli_stmt $stmt )

Fetch the result from a prepared statement into the variables bound by mysqli_stmt_bind_result.

Note:

Note that all columns must be bound by the application before calling mysqli_stmt_fetch.

Note:

Data are transferred unbuffered without calling <span class="function">mysqli_stmt_store_result which can decrease performance (but reduces memory cost).

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

返回值

Value Description
true Success. Data has been fetched
false Error occurred
null No more rows/data exists or data truncation occurred

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER by ID DESC LIMIT 150,5";

if ($stmt = $mysqli->prepare($query)) {

    /* execute statement */
    $stmt->execute();

    /* bind result variables */
    $stmt->bind_result($name, $code);

    /* fetch values */
    while ($stmt->fetch()) {
        printf ("%s (%s)\n", $name, $code);
    }

    /* close statement */
    $stmt->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER by ID DESC LIMIT 150,5";

if ($stmt = mysqli_prepare($link, $query)) {

    /* execute statement */
    mysqli_stmt_execute($stmt);

    /* bind result variables */
    mysqli_stmt_bind_result($stmt, $name, $code);

    /* fetch values */
    while (mysqli_stmt_fetch($stmt)) {
        printf ("%s (%s)\n", $name, $code);
    }

    /* close statement */
    mysqli_stmt_close($stmt);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Rockford (USA)
Tallahassee (USA)
Salinas (USA)
Santa Clarita (USA)
Springfield (USA)

参见

  • mysqli_prepare
  • mysqli_stmt_errno
  • mysqli_stmt_error
  • mysqli_stmt_bind_result

mysqli_stmt::$field_count

mysqli_stmt_field_count

Returns the number of columns in the given statement

说明

面向对象风格

int$mysqli_stmt->field_count;

过程化风格

int <span class="methodname">mysqli_stmt_field_count ( <span class="methodparam">mysqli_stmt $stmt )

Returns the number of columns in the prepared statement.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

返回值

Returns an integer representing the number of columns.

范例

示例 #1 面向对象风格

<?php

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

$code = 'FR';

$stmt = $mysqli->prepare("SELECT Name FROM Country WHERE Code=?");
$stmt->bind_param('s', $code);
$stmt->execute();
$row = $stmt->get_result()->fetch_row();
for ($i = 0; $i < $stmt->field_count; $i++) {
    printf("Value of column number %d is %s", $i, $row[$i]);
}

示例 #2 过程化风格

<?php

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = mysqli_connect("localhost", "my_user", "my_password", "world");

$code = 'FR';

$stmt = mysqli_prepare($mysqli, "SELECT Name FROM Country WHERE Code=?");
mysqli_stmt_bind_param($stmt, 's', $code);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_row($result);
for ($i = 0; $i < mysqli_stmt_field_count($stmt); $i++) {
    printf("Value of column number %d is %s", $i, $row[$i]);
}

以上例程的输出类似于:

Value of column number 0 is France

参见

  • mysqli_stmt_num_rows

mysqli_stmt::free_result

mysqli_stmt_free_result

Frees stored result memory for the given statement handle

说明

面向对象风格

public void mysqli_stmt::free_result ( <span class="methodparam">void )

过程化风格

void <span class="methodname">mysqli_stmt_free_result ( <span class="methodparam">mysqli_stmt $stmt )

Frees the result memory associated with the statement, which was allocated by mysqli_stmt_store_result.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

返回值

没有返回值。

参见

  • mysqli_stmt_store_result

mysqli_stmt::get_result

mysqli_stmt_get_result

Gets a result set from a prepared statement

说明

面向对象风格

public <span class="type">mysqli_result <span class="methodname">mysqli_stmt::get_result ( <span class="methodparam">void )

过程化风格

mysqli_result <span class="methodname">mysqli_stmt_get_result ( <span class="methodparam">mysqli_stmt $stmt )

Call to return a result set from a prepared statement query.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

返回值

Returns a resultset for successful SELECT queries, or false for other DML queries or on failure. The <span class="function">mysqli_errno function can be used to distinguish between the two types of failure.

仅 MySQL 原生驱动

仅可用于 mysqlnd

范例

示例 #1 面向对象风格

<?php 

$mysqli = new mysqli("127.0.0.1", "user", "password", "world"); 

if($mysqli->connect_error)
{
    die("$mysqli->connect_errno: $mysqli->connect_error");
}

$query = "SELECT Name, Population, Continent FROM Country WHERE Continent=? ORDER BY Name LIMIT 1";

$stmt = $mysqli->stmt_init();
if(!$stmt->prepare($query))
{
    print "Failed to prepare statement\n";
}
else
{
    $stmt->bind_param("s", $continent);

    $continent_array = array('Europe','Africa','Asia','North America');

    foreach($continent_array as $continent)
    {
        $stmt->execute();
        $result = $stmt->get_result();
        while ($row = $result->fetch_array(MYSQLI_NUM))
        {
            foreach ($row as $r)
            {
                print "$r ";
            }
            print "\n";
        }
    }
}

$stmt->close();
$mysqli->close();
?>

示例 #2 过程化风格

<?php 

$link = mysqli_connect("127.0.0.1", "user", "password", "world"); 

if (!$link)
{
    $error = mysqli_connect_error();
    $errno = mysqli_connect_errno();
    print "$errno: $error\n";
    exit();
}

$query = "SELECT Name, Population, Continent FROM Country WHERE Continent=? ORDER BY Name LIMIT 1";

$stmt = mysqli_stmt_init($link);
if(!mysqli_stmt_prepare($stmt, $query))
{
    print "Failed to prepare statement\n";
}
else
{
    mysqli_stmt_bind_param($stmt, "s", $continent);

    $continent_array = array('Europe','Africa','Asia','North America');

    foreach($continent_array as $continent)
    {
        mysqli_stmt_execute($stmt);
        $result = mysqli_stmt_get_result($stmt);
        while ($row = mysqli_fetch_array($result, MYSQLI_NUM))
        {
            foreach ($row as $r)
            {
                print "$r ";
            }
            print "\n";
        }
    }
}
mysqli_stmt_close($stmt);
mysqli_close($link);
?>

以上例程会输出:

Albania 3401200 Europe 
Algeria 31471000 Africa 
Afghanistan 22720000 Asia 
Anguilla 8000 North America 

参见

  • mysqli_prepare
  • mysqli_stmt_result_metadata
  • mysqli_stmt_fetch
  • mysqli_fetch_array
  • mysqli_stmt_store_result
  • mysqli_errno

mysqli_stmt::get_warnings

mysqli_stmt_get_warnings

Get result of SHOW WARNINGS

说明

面向对象风格

public object mysqli_stmt::get_warnings ( <span class="methodparam">void )

过程化风格

object <span class="methodname">mysqli_stmt_get_warnings ( <span class="methodparam">mysqli_stmt $stmt )

Warning

本函数还未编写文档,仅有参数列表。

mysqli_stmt::$insert_id

mysqli_stmt_insert_id

Get the ID generated from the previous INSERT operation

说明

面向对象风格

int$mysqli_stmt->insert_id;

过程化风格

mixed <span class="methodname">mysqli_stmt_insert_id ( <span class="methodparam">mysqli_stmt $stmt )

Warning

本函数还未编写文档,仅有参数列表。

mysqli_stmt::more_results

mysqli_stmt_more_results

Check if there are more query results from a multiple query

说明

面向对象风格

public bool mysqli_stmt::more_results ( <span class="methodparam">void )

过程化风格:

bool <span class="methodname">mysqli_stmt_more_results ( <span class="methodparam">mysql_stmt $stmt )

Checks if there are more query results from a multiple query.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

返回值

Returns true if more results exist, otherwise false.

仅 MySQL 原生驱动

仅可用于 mysqlnd

参见

  • mysqli_stmt::next_result
  • mysqli::multi_query

mysqli_stmt::next_result

mysqli_stmt_next_result

Reads the next result from a multiple query

说明

面向对象风格

public bool mysqli_stmt::next_result ( <span class="methodparam">void )

过程化风格:

bool <span class="methodname">mysqli_stmt_next_result ( <span class="methodparam">mysql_stmt $stmt )

Reads the next result from a multiple query.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

返回值

成功时返回 true, 或者在失败时返回 false

错误/异常

Emits an E_STRICT level error if a result set does not exist, and suggests using <span class="methodname">mysqli_stmt::more_results in these cases, before calling <span class="methodname">mysqli_stmt::next_result.

仅 MySQL 原生驱动

仅可用于 mysqlnd

参见

  • mysqli_stmt::more_results
  • mysqli::multi_query

mysqli_stmt::$num_rows

mysqli_stmt::num_rows

mysqli_stmt_num_rows

Return the number of rows in statements result set

说明

面向对象风格

int$mysqli_stmt->num_rows;

public int <span class="methodname">mysqli_stmt::num_rows ( <span class="methodparam">void )

过程化风格

int <span class="methodname">mysqli_stmt_num_rows ( <span class="methodparam">mysqli_stmt $stmt )

Returns the number of rows in the result set. The use of <span class="function">mysqli_stmt_num_rows depends on whether or not you used mysqli_stmt_store_result to buffer the entire result set in the statement handle.

If you use mysqli_stmt_store_result, mysqli_stmt_num_rows may be called immediately.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

返回值

An integer representing the number of rows in result set.

范例

示例 #1 面向对象风格

<?php
/* Open a connection */
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER BY Name LIMIT 20";
if ($stmt = $mysqli->prepare($query)) {

    /* execute query */
    $stmt->execute();

    /* store result */
    $stmt->store_result();

    printf("Number of rows: %d.\n", $stmt->num_rows);

    /* close statement */
    $stmt->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
/* Open a connection */
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER BY Name LIMIT 20";
if ($stmt = mysqli_prepare($link, $query)) {

    /* execute query */
    mysqli_stmt_execute($stmt);

    /* store result */
    mysqli_stmt_store_result($stmt);

    printf("Number of rows: %d.\n", mysqli_stmt_num_rows($stmt));

    /* close statement */
    mysqli_stmt_close($stmt);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Number of rows: 20.

参见

  • mysqli_stmt_affected_rows
  • mysqli_prepare
  • mysqli_stmt_store_result

mysqli_stmt::$param_count

mysqli_stmt_param_count

Returns the number of parameters for the given statement

说明

面向对象风格

int$mysqli_stmt->param_count;

过程化风格

int <span class="methodname">mysqli_stmt_param_count ( <span class="methodparam">mysqli_stmt $stmt )

Returns the number of parameter markers present in the prepared statement.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

返回值

Returns an integer representing the number of parameters.

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

if ($stmt = $mysqli->prepare("SELECT Name FROM Country WHERE Name=? OR Code=?")) {

    $marker = $stmt->param_count;
    printf("Statement has %d markers.\n", $marker);

    /* close statement */
    $stmt->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

if ($stmt = mysqli_prepare($link, "SELECT Name FROM Country WHERE Name=? OR Code=?")) {

    $marker = mysqli_stmt_param_count($stmt);
    printf("Statement has %d markers.\n", $marker);

    /* close statement */
    mysqli_stmt_close($stmt);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Statement has 2 markers.

参见

  • mysqli_prepare

mysqli_stmt::prepare

mysqli_stmt_prepare

Prepare an SQL statement for execution

说明

面向对象风格

public mixed mysqli_stmt::prepare ( <span class="methodparam">string $query )

过程化风格

bool <span class="methodname">mysqli_stmt_prepare ( <span class="methodparam">mysqli_stmt $stmt , <span class="type">string $query )

Prepares the SQL query pointed to by the null-terminated string query.

The parameter markers must be bound to application variables using <span class="function">mysqli_stmt_bind_param and/or <span class="function">mysqli_stmt_bind_result before executing the statement or fetching rows.

Note:

In the case where you pass a statement to <span class="function">mysqli_stmt_prepare that is longer than max_allowed_packet of the server, the returned error codes are different depending on whether you are using MySQL Native Driver (mysqlnd) or MySQL Client Library (libmysqlclient). The behavior is as follows:

  • mysqlnd on Linux returns an error code of 1153. The error message means “got a packet bigger than max_allowed_packet bytes”.

  • mysqlnd on Windows returns an error code 2006. This error message means “server has gone away”.

  • libmysqlclient on all platforms returns an error code 2006. This error message means “server has gone away”.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

query
The query, as a string. It must consist of a single SQL statement.

You can include one or more parameter markers in the SQL statement by embedding question mark (?) characters at the appropriate positions.

Note:

You should not add a terminating semicolon or \g to the statement.

Note:

The markers are legal only in certain places in SQL statements. For example, they are allowed in the VALUES() list of an INSERT statement (to specify column values for a row), or in a comparison with a column in a WHERE clause to specify a comparison value.

However, they are not allowed for identifiers (such as table or column names), in the select list that names the columns to be returned by a SELECT statement), or to specify both operands of a binary operator such as the = equal sign. The latter restriction is necessary because it would be impossible to determine the parameter type. In general, parameters are legal only in Data Manipulation Language (DML) statements, and not in Data Definition Language (DDL) statements.

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$city = "Amersfoort";

/* create a prepared statement */
$stmt =  $mysqli->stmt_init();
if ($stmt->prepare("SELECT District FROM City WHERE Name=?")) {

    /* bind parameters for markers */
    $stmt->bind_param("s", $city);

    /* execute query */
    $stmt->execute();

    /* bind result variables */
    $stmt->bind_result($district);

    /* fetch value */
    $stmt->fetch();

    printf("%s is in district %s\n", $city, $district);

    /* close statement */
    $stmt->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$city = "Amersfoort";

/* create a prepared statement */
$stmt = mysqli_stmt_init($link);
if (mysqli_stmt_prepare($stmt, 'SELECT District FROM City WHERE Name=?')) {

    /* bind parameters for markers */
    mysqli_stmt_bind_param($stmt, "s", $city);

    /* execute query */
    mysqli_stmt_execute($stmt);

    /* bind result variables */
    mysqli_stmt_bind_result($stmt, $district);

    /* fetch value */
    mysqli_stmt_fetch($stmt);

    printf("%s is in district %s\n", $city, $district);

    /* close statement */
    mysqli_stmt_close($stmt);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Amersfoort is in district Utrecht

参见

  • mysqli_stmt_init
  • mysqli_stmt_execute
  • mysqli_stmt_fetch
  • mysqli_stmt_bind_param
  • mysqli_stmt_bind_result
  • mysqli_stmt_get_result
  • mysqli_stmt_close

mysqli_stmt::reset

mysqli_stmt_reset

Resets a prepared statement

说明

面向对象风格

public bool mysqli_stmt::reset ( <span class="methodparam">void )

过程化风格

bool <span class="methodname">mysqli_stmt_reset ( <span class="methodparam">mysqli_stmt $stmt )

Resets a prepared statement on client and server to state after prepare.

It resets the statement on the server, data sent using <span class="function">mysqli_stmt_send_long_data, unbuffered result sets and current errors. It does not clear bindings or stored result sets. Stored result sets will be cleared when executing the prepared statement (or closing it).

To prepare a statement with another query use function <span class="function">mysqli_stmt_prepare.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

返回值

成功时返回 true, 或者在失败时返回 false

参见

  • mysqli_prepare

mysqli_stmt::result_metadata

mysqli_stmt_result_metadata

Returns result set metadata from a prepared statement

说明

面向对象风格

public <span class="type">mysqli_result <span class="methodname">mysqli_stmt::result_metadata ( <span class="methodparam">void )

过程化风格

mysqli_result <span class="methodname">mysqli_stmt_result_metadata ( <span class="methodparam">mysqli_stmt $stmt )

If a statement passed to mysqli_prepare is one that produces a result set, <span class="function">mysqli_stmt_result_metadata returns the result object that can be used to process the meta information such as total number of fields and individual field information.

Note:

This result set pointer can be passed as an argument to any of the field-based functions that process result set metadata, such as:

  • mysqli_num_fields

  • mysqli_fetch_field

  • mysqli_fetch_field_direct

  • mysqli_fetch_fields

  • mysqli_field_count

  • mysqli_field_seek

  • mysqli_field_tell

  • mysqli_free_result

The result set structure should be freed when you are done with it, which you can do by passing it to <span class="function">mysqli_free_result

Note:

The result set returned by <span class="function">mysqli_stmt_result_metadata contains only metadata. It does not contain any row results. The rows are obtained by using the statement handle with <span class="function">mysqli_stmt_fetch.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

返回值

Returns a result object or false if an error occurred.

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "test");

$mysqli->query("DROP TABLE IF EXISTS friends");
$mysqli->query("CREATE TABLE friends (id int, name varchar(20))");

$mysqli->query("INSERT INTO friends VALUES (1,'Hartmut'), (2, 'Ulf')");

$stmt = $mysqli->prepare("SELECT id, name FROM friends");
$stmt->execute();

/* get resultset for metadata */
$result = $stmt->result_metadata();

/* retrieve field information from metadata result set */
$field = $result->fetch_field();

printf("Fieldname: %s\n", $field->name);

/* close resultset */
$result->close();

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "test");

mysqli_query($link, "DROP TABLE IF EXISTS friends");
mysqli_query($link, "CREATE TABLE friends (id int, name varchar(20))");

mysqli_query($link, "INSERT INTO friends VALUES (1,'Hartmut'), (2, 'Ulf')");

$stmt = mysqli_prepare($link, "SELECT id, name FROM friends");
mysqli_stmt_execute($stmt);

/* get resultset for metadata */
$result = mysqli_stmt_result_metadata($stmt);

/* retrieve field information from metadata result set */
$field = mysqli_fetch_field($result);

printf("Fieldname: %s\n", $field->name);

/* close resultset */
mysqli_free_result($result);

/* close connection */
mysqli_close($link);
?>

参见

  • mysqli_prepare
  • mysqli_free_result

mysqli_stmt::send_long_data

mysqli_stmt_send_long_data

Send data in blocks

说明

面向对象风格

public bool mysqli_stmt::send_long_data ( <span class="methodparam">int $param_nr , string $data )

过程化风格

bool <span class="methodname">mysqli_stmt_send_long_data ( <span class="methodparam">mysqli_stmt $stmt , int $param_nr , <span class="type">string $data )

Allows to send parameter data to the server in pieces (or chunks), e.g. if the size of a blob exceeds the size of max_allowed_packet. This function can be called multiple times to send the parts of a character or binary data value for a column, which must be one of the TEXT or BLOB datatypes.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

param_nr
Indicates which parameter to associate the data with. Parameters are numbered beginning with 0.

data
A string containing data to be sent.

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 面向对象风格

<?php
$stmt = $mysqli->prepare("INSERT INTO messages (message) VALUES (?)");
$null = NULL;
$stmt->bind_param("b", $null);
$fp = fopen("messages.txt", "r");
while (!feof($fp)) {
    $stmt->send_long_data(0, fread($fp, 8192));
}
fclose($fp);
$stmt->execute();
?>

参见

  • mysqli_prepare
  • mysqli_stmt_bind_param

mysqli_stmt::$sqlstate

mysqli_stmt_sqlstate

Returns SQLSTATE error from previous statement operation

说明

面向对象风格

string$mysqli_stmt->sqlstate;

过程化风格

string <span class="methodname">mysqli_stmt_sqlstate ( <span class="methodparam">mysqli_stmt $stmt )

Returns a string containing the SQLSTATE error code for the most recently invoked prepared statement function that can succeed or fail. The error code consists of five characters. '00000' means no error. The values are specified by ANSI SQL and ODBC. For a list of possible values, see » http://dev.mysql.com/doc/mysql/en/error-handling.html.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

返回值

Returns a string containing the SQLSTATE error code for the last error. The error code consists of five characters. '00000' means no error.

注释

Note:

Note that not all MySQL errors are yet mapped to SQLSTATE's. The value HY000 (general error) is used for unmapped errors.

范例

示例 #1 面向对象风格

<?php
/* Open a connection */
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$mysqli->query("CREATE TABLE myCountry LIKE Country");
$mysqli->query("INSERT INTO myCountry SELECT * FROM Country");


$query = "SELECT Name, Code FROM myCountry ORDER BY Name";
if ($stmt = $mysqli->prepare($query)) {

    /* drop table */
    $mysqli->query("DROP TABLE myCountry");

    /* execute query */
    $stmt->execute();

    printf("Error: %s.\n", $stmt->sqlstate);

    /* close statement */
    $stmt->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
/* Open a connection */
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

mysqli_query($link, "CREATE TABLE myCountry LIKE Country");
mysqli_query($link, "INSERT INTO myCountry SELECT * FROM Country");


$query = "SELECT Name, Code FROM myCountry ORDER BY Name";
if ($stmt = mysqli_prepare($link, $query)) {

    /* drop table */
    mysqli_query($link, "DROP TABLE myCountry");

    /* execute query */
    mysqli_stmt_execute($stmt);

    printf("Error: %s.\n", mysqli_stmt_sqlstate($stmt));

    /* close statement */
    mysqli_stmt_close($stmt);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Error: 42S02.

参见

  • mysqli_stmt_errno
  • mysqli_stmt_error

mysqli_stmt::store_result

mysqli_stmt_store_result

Transfers a result set from a prepared statement

说明

面向对象风格

public bool mysqli_stmt::store_result ( <span class="methodparam">void )

过程化风格

bool <span class="methodname">mysqli_stmt_store_result ( <span class="methodparam">mysqli_stmt $stmt )

You must call mysqli_stmt_store_result for every query that successfully produces a result set (SELECT, SHOW, DESCRIBE, EXPLAIN), if and only if you want to buffer the complete result set by the client, so that the subsequent <span class="function">mysqli_stmt_fetch call returns buffered data.

Note:

It is unnecessary to call <span class="function">mysqli_stmt_store_result for other queries, but if you do, it will not harm or cause any notable performance loss in all cases. You can detect whether the query produced a result set by checking if <span class="function">mysqli_stmt_result_metadata returns false.

参数

stmt
仅以过程化样式:由 mysqli_stmt_init 返回的 statement 标识。

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 面向对象风格

<?php
/* Open a connection */
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER BY Name LIMIT 20";
if ($stmt = $mysqli->prepare($query)) {

    /* execute query */
    $stmt->execute();

    /* store result */
    $stmt->store_result();

    printf("Number of rows: %d.\n", $stmt->num_rows);

    /* free result */
    $stmt->free_result();

    /* close statement */
    $stmt->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
/* Open a connection */
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER BY Name LIMIT 20";
if ($stmt = mysqli_prepare($link, $query)) {

    /* execute query */
    mysqli_stmt_execute($stmt);

    /* store result */
    mysqli_stmt_store_result($stmt);

    printf("Number of rows: %d.\n", mysqli_stmt_num_rows($stmt));

    /* free result */
    mysqli_stmt_free_result($stmt);

    /* close statement */
    mysqli_stmt_close($stmt);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Number of rows: 20.

参见

  • mysqli_prepare
  • mysqli_stmt_result_metadata
  • mysqli_stmt_fetch

简介

代表从一个数据库查询中获取的结果集。

更新日志

版本 说明
5.4.0 Iterator support was added, as mysqli_result now implements Traversable.

类摘要

mysqli_result

class mysqli_result {

/* 属性 */

int$mysqli_result->current_field ;

int$mysqli_result->field_count;

array$mysqli_result->lengths;

int$mysqli_result->num_rows;

/* 方法 */

int <span class="methodname">mysqli_field_tell ( <span class="methodparam">mysqli_result $result )

public bool data_seek ( <span class="methodparam">int $offset )

public mixed fetch_all ([ <span class="methodparam">int $resulttype<span class="initializer"> = MYSQLI_NUM ] )

public mixed fetch_array ([ <span class="methodparam">int $resulttype<span class="initializer"> = MYSQLI_BOTH ] )

public array fetch_assoc ( <span class="methodparam">void )

public object fetch_field_direct ( <span class="methodparam">int $fieldnr )

public object fetch_field ( <span class="methodparam">void )

public array fetch_fields ( <span class="methodparam">void )

public object fetch_object ([ <span class="methodparam">string $class_name<span class="initializer"> = "stdClass" [, <span class="methodparam">array $params ]] )

public mixed fetch_row ( <span class="methodparam">void )

int <span class="methodname">mysqli_num_fields ( <span class="methodparam">mysqli_result $result )

public bool field_seek ( <span class="methodparam">int $fieldnr )

public void free ( <span class="methodparam">void )

array <span class="methodname">mysqli_fetch_lengths ( <span class="methodparam">mysqli_result $result )

int <span class="methodname">mysqli_num_rows ( <span class="methodparam">mysqli_result $result )

}

mysqli_result::$current_field

mysqli_field_tell

Get current field offset of a result pointer

说明

面向对象风格

int$mysqli_result->current_field ;

过程化风格

int <span class="methodname">mysqli_field_tell ( <span class="methodparam">mysqli_result $result )

Returns the position of the field cursor used for the last <span class="function">mysqli_fetch_field call. This value can be used as an argument to <span class="function">mysqli_field_seek.

参数

result
仅以过程化样式:由 mysqli_query,<span class="function">mysqli_store_result 或 <span class="function">mysqli_use_result返回的结果集标识。

返回值

Returns current offset of field cursor.

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, SurfaceArea from Country ORDER BY Code LIMIT 5";

if ($result = $mysqli->query($query)) {

    /* Get field information for all columns */
    while ($finfo = $result->fetch_field()) {

        /* get fieldpointer offset */
        $currentfield = $result->current_field;

        printf("Column %d:\n", $currentfield);
        printf("Name:     %s\n", $finfo->name);
        printf("Table:    %s\n", $finfo->table);
        printf("max. Len: %d\n", $finfo->max_length);
        printf("Flags:    %d\n", $finfo->flags);
        printf("Type:     %d\n\n", $finfo->type);
    }
    $result->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, SurfaceArea from Country ORDER BY Code LIMIT 5";

if ($result = mysqli_query($link, $query)) {

    /* Get field information for all fields */
    while ($finfo = mysqli_fetch_field($result)) {

        /* get fieldpointer offset */
        $currentfield = mysqli_field_tell($result);

        printf("Column %d:\n", $currentfield);
        printf("Name:     %s\n", $finfo->name);
        printf("Table:    %s\n", $finfo->table);
        printf("max. Len: %d\n", $finfo->max_length);
        printf("Flags:    %d\n", $finfo->flags);
        printf("Type:     %d\n\n", $finfo->type);
    }
    mysqli_free_result($result);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Column 1:
Name:     Name
Table:    Country
max. Len: 11
Flags:    1
Type:     254

Column 2:
Name:     SurfaceArea
Table:    Country
max. Len: 10
Flags:    32769
Type:     4

参见

  • mysqli_fetch_field
  • mysqli_field_seek

mysqli_result::data_seek

mysqli_data_seek

Adjusts the result pointer to an arbitrary row in the result

说明

面向对象风格

public bool mysqli_result::data_seek ( <span class="methodparam">int $offset )

过程化风格

bool <span class="methodname">mysqli_data_seek ( <span class="methodparam">mysqli_result $result , <span class="type">int $offset )

The mysqli_data_seek function seeks to an arbitrary result pointer specified by the offset in the result set.

参数

result
仅以过程化样式:由 mysqli_query,<span class="function">mysqli_store_result 或 <span class="function">mysqli_use_result返回的结果集标识。

offset
The field offset. Must be between zero and the total number of rows minus one (0..mysqli_num_rows - 1).

返回值

成功时返回 true, 或者在失败时返回 false

注释

Note:

This function can only be used with buffered results attained from the use of the mysqli_store_result or mysqli_query functions.

范例

示例 #1 面向对象风格

<?php
/* Open a connection */
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER BY Name";
if ($result = $mysqli->query($query)) {

    /* seek to row no. 400 */
    $result->data_seek(399);

    /* fetch row */
    $row = $result->fetch_row();

    printf ("City: %s  Countrycode: %s\n", $row[0], $row[1]);

    /* free result set*/
    $result->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
/* Open a connection */
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (!$link) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER BY Name";

if ($result = mysqli_query($link, $query)) {

    /* seek to row no. 400 */
    mysqli_data_seek($result, 399);

    /* fetch row */
    $row = mysqli_fetch_row($result);

    printf ("City: %s  Countrycode: %s\n", $row[0], $row[1]);

    /* free result set*/
    mysqli_free_result($result);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

City: Benin City  Countrycode: NGA

参见

  • mysqli_store_result
  • mysqli_fetch_row
  • mysqli_fetch_array
  • mysqli_fetch_assoc
  • mysqli_fetch_object
  • mysqli_query
  • mysqli_num_rows

mysqli_result::fetch_all

mysqli_fetch_all

Fetches all result rows as an associative array, a numeric array, or both

说明

面向对象风格

public mixed mysqli_result::fetch_all ([ <span class="methodparam">int $resulttype<span class="initializer"> = MYSQLI_NUM ] )

过程化风格

mixed <span class="methodname">mysqli_fetch_all ( <span class="methodparam">mysqli_result $result [, <span class="type">int $resulttype = MYSQLI_NUM ] )

mysqli_fetch_all fetches all result rows and returns the result set as an associative array, a numeric array, or both.

参数

result
仅以过程化样式:由 mysqli_query,<span class="function">mysqli_store_result 或 <span class="function">mysqli_use_result返回的结果集标识。

resulttype
This optional parameter is a constant indicating what type of array should be produced from the current row data. The possible values for this parameter are the constants MYSQLI_ASSOC, MYSQLI_NUM, or MYSQLI_BOTH.

返回值

Returns an array of associative or numeric arrays holding result rows.

仅 MySQL 原生驱动

仅可用于 mysqlnd

As mysqli_fetch_all returns all the rows as an array in a single step, it may consume more memory than some similar functions such as <span class="function">mysqli_fetch_array, which only returns one row at a time from the result set. Further, if you need to iterate over the result set, you will need a looping construct that will further impact performance. For these reasons <span class="function">mysqli_fetch_all should only be used in those situations where the fetched result set will be sent to another layer for processing.

参见

  • mysqli_fetch_array
  • mysqli_query

mysqli_result::fetch_array

mysqli_fetch_array

Fetch a result row as an associative, a numeric array, or both

说明

面向对象风格

public mixed mysqli_result::fetch_array ([ <span class="methodparam">int $resulttype<span class="initializer"> = MYSQLI_BOTH ] )

过程化风格

mixed <span class="methodname">mysqli_fetch_array ( <span class="methodparam">mysqli_result $result [, <span class="type">int $resulttype = MYSQLI_BOTH ] )

Returns an array that corresponds to the fetched row or null if there are no more rows for the resultset represented by the result parameter.

mysqli_fetch_array is an extended version of the mysqli_fetch_row function. In addition to storing the data in the numeric indices of the result array, the mysqli_fetch_array function can also store the data in associative indices, using the field names of the result set as keys.

Note: <span class="simpara">此函数返回的字段名大小写敏感

Note: 此函数将 NULL 字段设置为 PHP null 值。

If two or more columns of the result have the same field names, the last column will take precedence and overwrite the earlier data. In order to access multiple columns with the same name, the numerically indexed version of the row must be used.

参数

result
仅以过程化样式:由 mysqli_query,<span class="function">mysqli_store_result 或 <span class="function">mysqli_use_result返回的结果集标识。

resulttype
This optional parameter is a constant indicating what type of array should be produced from the current row data. The possible values for this parameter are the constants MYSQLI_ASSOC, MYSQLI_NUM, or MYSQLI_BOTH.

By using the MYSQLI_ASSOC constant this function will behave identically to the mysqli_fetch_assoc, while MYSQLI_NUM will behave identically to the <span class="function">mysqli_fetch_row function. The final option MYSQLI_BOTH will create a single array with the attributes of both.

返回值

Returns an array of strings that corresponds to the fetched row or null if there are no more rows in resultset.

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if ($mysqli->connect_errno) {
    printf("Connect failed: %s\n", $mysqli->connect_error);
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER by ID LIMIT 3";
$result = $mysqli->query($query);

/* numeric array */
$row = $result->fetch_array(MYSQLI_NUM);
printf ("%s (%s)\n", $row[0], $row[1]);

/* associative array */
$row = $result->fetch_array(MYSQLI_ASSOC);
printf ("%s (%s)\n", $row["Name"], $row["CountryCode"]);

/* associative and numeric array */
$row = $result->fetch_array(MYSQLI_BOTH);
printf ("%s (%s)\n", $row[0], $row["CountryCode"]);

/* free result set */
$result->free();

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER by ID LIMIT 3";
$result = mysqli_query($link, $query);

/* numeric array */
$row = mysqli_fetch_array($result, MYSQLI_NUM);
printf ("%s (%s)\n", $row[0], $row[1]);

/* associative array */
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
printf ("%s (%s)\n", $row["Name"], $row["CountryCode"]);

/* associative and numeric array */
$row = mysqli_fetch_array($result, MYSQLI_BOTH);
printf ("%s (%s)\n", $row[0], $row["CountryCode"]);

/* free result set */
mysqli_free_result($result);

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Kabul (AFG)
Qandahar (AFG)
Herat (AFG)

参见

  • mysqli_fetch_assoc
  • mysqli_fetch_row
  • mysqli_fetch_object
  • mysqli_query
  • mysqli_data_seek

mysqli_result::fetch_assoc

mysqli_fetch_assoc

Fetch a result row as an associative array

说明

面向对象风格

public array mysqli_result::fetch_assoc ( <span class="methodparam">void )

过程化风格

array <span class="methodname">mysqli_fetch_assoc ( <span class="methodparam">mysqli_result $result )

Returns an associative array that corresponds to the fetched row or null if there are no more rows.

Note: <span class="simpara">此函数返回的字段名大小写敏感

Note: 此函数将 NULL 字段设置为 PHP null 值。

参数

result
仅以过程化样式:由 mysqli_query,<span class="function">mysqli_store_result 或 <span class="function">mysqli_use_result返回的结果集标识。

返回值

Returns an associative array of strings representing the fetched row in the result set, where each key in the array represents the name of one of the result set's columns or null if there are no more rows in resultset.

If two or more columns of the result have the same field names, the last column will take precedence. To access the other column(s) of the same name, you either need to access the result with numeric indices by using mysqli_fetch_row or add alias names.

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if ($mysqli->connect_errno) {
    printf("Connect failed: %s\n", $mysqli->connect_error);
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER by ID DESC LIMIT 50,5";

if ($result = $mysqli->query($query)) {

    /* fetch associative array */
    while ($row = $result->fetch_assoc()) {
        printf ("%s (%s)\n", $row["Name"], $row["CountryCode"]);
    }

    /* free result set */
    $result->free();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER by ID DESC LIMIT 50,5";

if ($result = mysqli_query($link, $query)) {

    /* fetch associative array */
    while ($row = mysqli_fetch_assoc($result)) {
        printf ("%s (%s)\n", $row["Name"], $row["CountryCode"]);
    }

    /* free result set */
    mysqli_free_result($result);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Pueblo (USA)
Arvada (USA)
Cape Coral (USA)
Green Bay (USA)
Santa Clara (USA)

示例 #3 A mysqli_result example comparing iterator usage

<?php
$c = mysqli_connect('127.0.0.1','user', 'pass');

// Using iterators (support was added with PHP 5.4)
foreach ( $c->query('SELECT user,host FROM mysql.user') as $row ) {
    printf("'%s'@'%s'\n", $row['user'], $row['host']);
}

echo "\n==================\n";

// Not using iterators
$result = $c->query('SELECT user,host FROM mysql.user');
while ($row = $result->fetch_assoc()) {
    printf("'%s'@'%s'\n", $row['user'], $row['host']);
}

?>

以上例程的输出类似于:

'root'@'192.168.1.1'
'root'@'127.0.0.1'
'dude'@'localhost'
'lebowski'@'localhost'

==================

'root'@'192.168.1.1'
'root'@'127.0.0.1'
'dude'@'localhost'
'lebowski'@'localhost'

参见

  • mysqli_fetch_array
  • mysqli_fetch_row
  • mysqli_fetch_object
  • mysqli_query
  • mysqli_data_seek

mysqli_result::fetch_field_direct

mysqli_fetch_field_direct

Fetch meta-data for a single field

说明

面向对象风格

public object mysqli_result::fetch_field_direct ( int $fieldnr )

过程化风格

object <span class="methodname">mysqli_fetch_field_direct ( <span class="methodparam">mysqli_result $result , <span class="type">int $fieldnr )

Returns an object which contains field definition information from the specified result set.

参数

result
仅以过程化样式:由 mysqli_query,<span class="function">mysqli_store_result 或 <span class="function">mysqli_use_result返回的结果集标识。

fieldnr
The field number. This value must be in the range from 0 to number of fields - 1.

返回值

Returns an object which contains field definition information or false if no field information for specified fieldnr is available.

Attribute Description
name The name of the column
orgname Original column name if an alias was specified
table The name of the table this field belongs to (if not calculated)
orgtable Original table name if an alias was specified
def The default value for this field, represented as a string
max_length The maximum width of the field for the result set.
length The width of the field, as specified in the table definition.
charsetnr The character set number for the field.
flags An integer representing the bit-flags for the field.
type The data type used for this field
decimals The number of decimals used (for numeric fields)

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, SurfaceArea from Country ORDER BY Name LIMIT 5";

if ($result = $mysqli->query($query)) {

    /* Get field information for column 'SurfaceArea' */
    $finfo = $result->fetch_field_direct(1);

    printf("Name:     %s\n", $finfo->name);
    printf("Table:    %s\n", $finfo->table);
    printf("max. Len: %d\n", $finfo->max_length);
    printf("Flags:    %d\n", $finfo->flags);
    printf("Type:     %d\n", $finfo->type);

    $result->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, SurfaceArea from Country ORDER BY Name LIMIT 5";

if ($result = mysqli_query($link, $query)) {

    /* Get field information for column 'SurfaceArea' */
    $finfo = mysqli_fetch_field_direct($result, 1);

    printf("Name:     %s\n", $finfo->name);
    printf("Table:    %s\n", $finfo->table);
    printf("max. Len: %d\n", $finfo->max_length);
    printf("Flags:    %d\n", $finfo->flags);
    printf("Type:     %d\n", $finfo->type);

    mysqli_free_result($result);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Name:     SurfaceArea
Table:    Country
max. Len: 10
Flags:    32769
Type:     4

参见

  • mysqli_num_fields
  • mysqli_fetch_field
  • mysqli_fetch_fields

mysqli_result::fetch_field

mysqli_fetch_field

Returns the next field in the result set

说明

面向对象风格

public object mysqli_result::fetch_field ( <span class="methodparam">void )

过程化风格

object <span class="methodname">mysqli_fetch_field ( <span class="methodparam">mysqli_result $result )

Returns the definition of one column of a result set as an object. Call this function repeatedly to retrieve information about all columns in the result set.

参数

result
仅以过程化样式:由 mysqli_query,<span class="function">mysqli_store_result 或 <span class="function">mysqli_use_result返回的结果集标识。

返回值

Returns an object which contains field definition information or false if no field information is available.

Property Description
name The name of the column
orgname Original column name if an alias was specified
table The name of the table this field belongs to (if not calculated)
orgtable Original table name if an alias was specified
def Reserved for default value, currently always ""
db Database (since PHP 5.3.6)
catalog The catalog name, always "def" (since PHP 5.3.6)
max_length The maximum width of the field for the result set.
length The width of the field, as specified in the table definition.
charsetnr The character set number for the field.
flags An integer representing the bit-flags for the field.
type The data type used for this field
decimals The number of decimals used (for integer fields)

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, SurfaceArea from Country ORDER BY Code LIMIT 5";

if ($result = $mysqli->query($query)) {

    /* Get field information for all columns */
    while ($finfo = $result->fetch_field()) {

        printf("Name:     %s\n", $finfo->name);
        printf("Table:    %s\n", $finfo->table);
        printf("max. Len: %d\n", $finfo->max_length);
        printf("Flags:    %d\n", $finfo->flags);
        printf("Type:     %d\n\n", $finfo->type);
    }
    $result->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, SurfaceArea from Country ORDER BY Code LIMIT 5";

if ($result = mysqli_query($link, $query)) {

    /* Get field information for all fields */
    while ($finfo = mysqli_fetch_field($result)) {

        printf("Name:     %s\n", $finfo->name);
        printf("Table:    %s\n", $finfo->table);
        printf("max. Len: %d\n", $finfo->max_length);
        printf("Flags:    %d\n", $finfo->flags);
        printf("Type:     %d\n\n", $finfo->type);
    }
    mysqli_free_result($result);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Name:     Name
Table:    Country
max. Len: 11
Flags:    1
Type:     254

Name:     SurfaceArea
Table:    Country
max. Len: 10
Flags:    32769
Type:     4

参见

  • mysqli_num_fields
  • mysqli_fetch_field_direct
  • mysqli_fetch_fields
  • mysqli_field_seek

mysqli_result::fetch_fields

mysqli_fetch_fields

Returns an array of objects representing the fields in a result set

说明

面向对象风格

public array mysqli_result::fetch_fields ( <span class="methodparam">void )

过程化风格

array <span class="methodname">mysqli_fetch_fields ( <span class="methodparam">mysqli_result $result )

This function serves an identical purpose to the <span class="function">mysqli_fetch_field function with the single difference that, instead of returning one object at a time for each field, the columns are returned as an array of objects.

参数

result
仅以过程化样式:由 mysqli_query,<span class="function">mysqli_store_result 或 <span class="function">mysqli_use_result返回的结果集标识。

返回值

Returns an array of objects which contains field definition information or false if no field information is available.

Property Description
name The name of the column
orgname Original column name if an alias was specified
table The name of the table this field belongs to (if not calculated)
orgtable Original table name if an alias was specified
max_length The maximum width of the field for the result set.
length The width of the field, in bytes, as specified in the table definition. Note that this number (bytes) might differ from your table definition value (characters), depending on the character set you use. For example, the character set utf8 has 3 bytes per character, so varchar(10) will return a length of 30 for utf8 (10*3), but return 10 for latin1 (10*1).
charsetnr The character set number (id) for the field.
flags An integer representing the bit-flags for the field.
type The data type used for this field
decimals The number of decimals used (for integer fields)

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli("127.0.0.1", "root", "foofoo", "sakila");

/* check connection */
if ($mysqli->connect_errno) {
    printf("Connect failed: %s\n", $mysqli->connect_error);
    exit();
}

foreach (array('latin1', 'utf8') as $charset) {

    // Set character set, to show its impact on some values (e.g., length in bytes)
    $mysqli->set_charset($charset);

    $query = "SELECT actor_id, last_name from actor ORDER BY actor_id";

    echo "======================\n";
    echo "Character Set: $charset\n";
    echo "======================\n";

    if ($result = $mysqli->query($query)) {

        /* Get field information for all columns */
        $finfo = $result->fetch_fields();

        foreach ($finfo as $val) {
            printf("Name:      %s\n",   $val->name);
            printf("Table:     %s\n",   $val->table);
            printf("Max. Len:  %d\n",   $val->max_length);
            printf("Length:    %d\n",   $val->length);
            printf("charsetnr: %d\n",   $val->charsetnr);
            printf("Flags:     %d\n",   $val->flags);
            printf("Type:      %d\n\n", $val->type);
        }
        $result->free();
    }
}
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link = mysqli_connect("127.0.0.1", "my_user", "my_password", "sakila");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

foreach (array('latin1', 'utf8') as $charset) {

    // Set character set, to show its impact on some values (e.g., length in bytes)
    mysqli_set_charset($link, $charset);

    $query = "SELECT actor_id, last_name from actor ORDER BY actor_id";

    echo "======================\n";
    echo "Character Set: $charset\n";
    echo "======================\n";

    if ($result = mysqli_query($link, $query)) {

        /* Get field information for all columns */
        $finfo = mysqli_fetch_fields($result);

        foreach ($finfo as $val) {
            printf("Name:      %s\n",   $val->name);
            printf("Table:     %s\n",   $val->table);
            printf("Max. Len:  %d\n",   $val->max_length);
            printf("Length:    %d\n",   $val->length);
            printf("charsetnr: %d\n",   $val->charsetnr);
            printf("Flags:     %d\n",   $val->flags);
            printf("Type:      %d\n\n", $val->type);
        }
        mysqli_free_result($result);
    }
}

mysqli_close($link);
?>

以上例程会输出:

======================
Character Set: latin1
======================
Name:      actor_id
Table:     actor
Max. Len:  3
Length:    5
charsetnr: 63
Flags:     49699
Type:      2

Name:      last_name
Table:     actor
Max. Len:  12
Length:    45
charsetnr: 8
Flags:     20489
Type:      253

======================
Character Set: utf8
======================
Name:      actor_id
Table:     actor
Max. Len:  3
Length:    5
charsetnr: 63
Flags:     49699
Type:      2

Name:      last_name
Table:     actor
Max. Len:  12
Length:    135
charsetnr: 33
Flags:     20489

参见

  • mysqli_num_fields
  • mysqli_fetch_field_direct
  • mysqli_fetch_field

mysqli_result::fetch_object

mysqli_fetch_object

Returns the current row of a result set as an object

说明

面向对象风格

public object mysqli_result::fetch_object ([ <span class="methodparam">string $class_name<span class="initializer"> = "stdClass" [, <span class="methodparam">array $params ]] )

过程化风格

object <span class="methodname">mysqli_fetch_object ( <span class="methodparam">mysqli_result $result [, <span class="type">string $class_name = "stdClass" [, <span class="type">array $params ]] )

The mysqli_fetch_object will return the current row result set as an object where the attributes of the object represent the names of the fields found within the result set.

Note that mysqli_fetch_object sets the properties of the object before calling the object constructor.

参数

result
仅以过程化样式:由 mysqli_query,<span class="function">mysqli_store_result 或 <span class="function">mysqli_use_result返回的结果集标识。

class_name
The name of the class to instantiate, set the properties of and return. If not specified, a stdClass object is returned.

params
An optional array of parameters to pass to the constructor for class_name objects.

返回值

Returns an object with string properties that corresponds to the fetched row or null if there are no more rows in resultset.

Note: <span class="simpara">此函数返回的字段名大小写敏感

Note: 此函数将 NULL 字段设置为 PHP null 值。

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER by ID DESC LIMIT 50,5";

if ($result = $mysqli->query($query)) {

    /* fetch object array */
    while ($obj = $result->fetch_object()) {
        printf ("%s (%s)\n", $obj->Name, $obj->CountryCode);
    }

    /* free result set */
    $result->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER by ID DESC LIMIT 50,5";

if ($result = mysqli_query($link, $query)) {

    /* fetch associative array */
    while ($obj = mysqli_fetch_object($result)) {
        printf ("%s (%s)\n", $obj->Name, $obj->CountryCode);
    }

    /* free result set */
    mysqli_free_result($result);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Pueblo (USA)
Arvada (USA)
Cape Coral (USA)
Green Bay (USA)
Santa Clara (USA)

参见

  • mysqli_fetch_array
  • mysqli_fetch_assoc
  • mysqli_fetch_row
  • mysqli_query
  • mysqli_data_seek

mysqli_result::fetch_row

mysqli_fetch_row

Get a result row as an enumerated array

说明

面向对象风格

public mixed mysqli_result::fetch_row ( <span class="methodparam">void )

过程化风格

mixed <span class="methodname">mysqli_fetch_row ( <span class="methodparam">mysqli_result $result )

Fetches one row of data from the result set and returns it as an enumerated array, where each column is stored in an array offset starting from 0 (zero). Each subsequent call to this function will return the next row within the result set, or null if there are no more rows.

参数

result
仅以过程化样式:由 mysqli_query,<span class="function">mysqli_store_result 或 <span class="function">mysqli_use_result返回的结果集标识。

返回值

mysqli_fetch_row returns an array of strings that corresponds to the fetched row or null if there are no more rows in result set.

Note: 此函数将 NULL 字段设置为 PHP null 值。

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER by ID DESC LIMIT 50,5";

if ($result = $mysqli->query($query)) {

    /* fetch object array */
    while ($row = $result->fetch_row()) {
        printf ("%s (%s)\n", $row[0], $row[1]);
    }

    /* free result set */
    $result->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER by ID DESC LIMIT 50,5";

if ($result = mysqli_query($link, $query)) {

    /* fetch associative array */
    while ($row = mysqli_fetch_row($result)) {
        printf ("%s (%s)\n", $row[0], $row[1]);
    }

    /* free result set */
    mysqli_free_result($result);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Pueblo (USA)
Arvada (USA)
Cape Coral (USA)
Green Bay (USA)
Santa Clara (USA)

参见

  • mysqli_fetch_array
  • mysqli_fetch_assoc
  • mysqli_fetch_object
  • mysqli_query
  • mysqli_data_seek

mysqli_result::$field_count

mysqli_num_fields

Get the number of fields in a result

说明

面向对象风格

int$mysqli_result->field_count;

过程化风格

int <span class="methodname">mysqli_num_fields ( <span class="methodparam">mysqli_result $result )

Returns the number of fields from specified result set.

参数

result
仅以过程化样式:由 mysqli_query,<span class="function">mysqli_store_result 或 <span class="function">mysqli_use_result返回的结果集标识。

返回值

The number of fields from a result set.

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

if ($result = $mysqli->query("SELECT * FROM City ORDER BY ID LIMIT 1")) {

    /* determine number of fields in result set */
    $field_cnt = $result->field_count;

    printf("Result set has %d fields.\n", $field_cnt);

    /* close result set */
    $result->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

if ($result = mysqli_query($link, "SELECT * FROM City ORDER BY ID LIMIT 1")) {

    /* determine number of fields in result set */
    $field_cnt = mysqli_num_fields($result);

    printf("Result set has %d fields.\n", $field_cnt);

    /* close result set */
    mysqli_free_result($result);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Result set has 5 fields.

参见

  • mysqli_fetch_field

mysqli_result::field_seek

mysqli_field_seek

Set result pointer to a specified field offset

说明

面向对象风格

public bool mysqli_result::field_seek ( <span class="methodparam">int $fieldnr )

过程化风格

bool <span class="methodname">mysqli_field_seek ( <span class="methodparam">mysqli_result $result , <span class="type">int $fieldnr )

Sets the field cursor to the given offset. The next call to <span class="function">mysqli_fetch_field will retrieve the field definition of the column associated with that offset.

Note:

To seek to the beginning of a row, pass an offset value of zero.

参数

result
仅以过程化样式:由 mysqli_query,<span class="function">mysqli_store_result 或 <span class="function">mysqli_use_result返回的结果集标识。

fieldnr
The field number. This value must be in the range from 0 to number of fields - 1.

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, SurfaceArea from Country ORDER BY Code LIMIT 5";

if ($result = $mysqli->query($query)) {

    /* Get field information for 2nd column */
    $result->field_seek(1);
    $finfo = $result->fetch_field();

    printf("Name:     %s\n", $finfo->name);
    printf("Table:    %s\n", $finfo->table);
    printf("max. Len: %d\n", $finfo->max_length);
    printf("Flags:    %d\n", $finfo->flags);
    printf("Type:     %d\n\n", $finfo->type);

    $result->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, SurfaceArea from Country ORDER BY Code LIMIT 5";

if ($result = mysqli_query($link, $query)) {

    /* Get field information for 2nd column */
    mysqli_field_seek($result, 1);
    $finfo = mysqli_fetch_field($result);

    printf("Name:     %s\n", $finfo->name);
    printf("Table:    %s\n", $finfo->table);
    printf("max. Len: %d\n", $finfo->max_length);
    printf("Flags:    %d\n", $finfo->flags);
    printf("Type:     %d\n\n", $finfo->type);

    mysqli_free_result($result);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Name:     SurfaceArea
Table:    Country
max. Len: 10
Flags:    32769
Type:     4

参见

  • mysqli_fetch_field

mysqli_result::free

mysqli_result::close

mysqli_result::free_result

mysqli_free_result

Frees the memory associated with a result

说明

面向对象风格

public void mysqli_result::free ( <span class="methodparam">void )

public void mysqli_result::close ( <span class="methodparam">void )

public void mysqli_result::free_result ( <span class="methodparam">void )

过程化风格

void <span class="methodname">mysqli_free_result ( <span class="methodparam">mysqli_result $result )

Frees the memory associated with the result.

参数

result
仅以过程化样式:由 mysqli_query,<span class="function">mysqli_store_result 或 <span class="function">mysqli_use_result返回的结果集标识。

返回值

没有返回值。

参见

  • mysqli_query
  • mysqli_stmt_get_result
  • mysqli_store_result
  • mysqli_use_result

mysqli_result::$lengths

mysqli_fetch_lengths

Returns the lengths of the columns of the current row in the result set

说明

面向对象风格

array$mysqli_result->lengths;

过程化风格

array <span class="methodname">mysqli_fetch_lengths ( <span class="methodparam">mysqli_result $result )

The mysqli_fetch_lengths function returns an array containing the lengths of every column of the current row within the result set.

参数

result
仅以过程化样式:由 mysqli_query,<span class="function">mysqli_store_result 或 <span class="function">mysqli_use_result返回的结果集标识。

返回值

An array of integers representing the size of each column (not including any terminating null characters). false if an error occurred.

mysqli_fetch_lengths is valid only for the current row of the result set. It returns false if you call it before calling mysqli_fetch_row/array/object or after retrieving all rows in the result.

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT * from Country ORDER BY Code LIMIT 1";

if ($result = $mysqli->query($query)) {

    $row = $result->fetch_row();

    /* display column lengths */
    foreach ($result->lengths as $i => $val) {
        printf("Field %2d has Length %2d\n", $i+1, $val);
    }
    $result->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT * from Country ORDER BY Code LIMIT 1";

if ($result = mysqli_query($link, $query)) {

    $row = mysqli_fetch_row($result);

    /* display column lengths */
    foreach (mysqli_fetch_lengths($result) as $i => $val) {
        printf("Field %2d has Length %2d\n", $i+1, $val);
    }
    mysqli_free_result($result);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Field  1 has Length  3
Field  2 has Length  5
Field  3 has Length 13
Field  4 has Length  9
Field  5 has Length  6
Field  6 has Length  1
Field  7 has Length  6
Field  8 has Length  4
Field  9 has Length  6
Field 10 has Length  6
Field 11 has Length  5
Field 12 has Length 44
Field 13 has Length  7
Field 14 has Length  3
Field 15 has Length  2

mysqli_result::$num_rows

mysqli_num_rows

Gets the number of rows in a result

说明

面向对象风格

int$mysqli_result->num_rows;

过程化风格

int <span class="methodname">mysqli_num_rows ( <span class="methodparam">mysqli_result $result )

Returns the number of rows in the result set.

The behaviour of mysqli_num_rows depends on whether buffered or unbuffered result sets are being used. For unbuffered result sets, mysqli_num_rows will not return the correct number of rows until all the rows in the result have been retrieved.

参数

result
仅以过程化样式:由 mysqli_query,<span class="function">mysqli_store_result 或 <span class="function">mysqli_use_result返回的结果集标识。

返回值

Returns number of rows in the result set.

Note:

If the number of rows is greater than PHP_INT_MAX, the number will be returned as a string.

范例

示例 #1 面向对象风格

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

if ($result = $mysqli->query("SELECT Code, Name FROM Country ORDER BY Name")) {

    /* determine number of rows result set */
    $row_cnt = $result->num_rows;

    printf("Result set has %d rows.\n", $row_cnt);

    /* close result set */
    $result->close();
}

/* close connection */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

if ($result = mysqli_query($link, "SELECT Code, Name FROM Country ORDER BY Name")) {

    /* determine number of rows result set */
    $row_cnt = mysqli_num_rows($result);

    printf("Result set has %d rows.\n", $row_cnt);

    /* close result set */
    mysqli_free_result($result);
}

/* close connection */
mysqli_close($link);
?>

以上例程会输出:

Result set has 239 rows.

参见

  • mysqli_affected_rows
  • mysqli_store_result
  • mysqli_use_result
  • mysqli_query

简介

MySQLi 驱动.

类摘要

MySQLi_Driver

class MySQLi_Driver {

/* 属性 */

public <span class="modifier">readonly string $client_info ;

public <span class="modifier">readonly string $client_version ;

public <span class="modifier">readonly string $driver_version ;

public <span class="modifier">readonly string $embedded ;

public bool $reconnect ;

public int $report_mode ;

/* 方法 */

public void mysqli_driver::embedded_server_end ( void )

public bool mysqli_driver::embedded_server_start ( int $start , <span class="type">array $arguments , <span class="methodparam">array $groups )

bool <span class="methodname">mysqli_report ( <span class="methodparam">int $flags )

}

属性

client_info
客户端API头版本(比如:(string)"5.1.49")

client_version
客户端版本(比如:(int)50149)

driver_version
Mysqli驱动版本(比如:(int)101009)

embedded
是否开启了MySQLi嵌入式支持。

reconnect
允许或阻止重连接(查看INI指令中的mysqli.reconnect)

report_mode
设置为MYSQLI_REPORT_OFF, MYSQLI_REPORT_ALL或者 MYSQLI_REPORT_STRICT (为错误抛出异常,译注:需要和MYSQLI_REPORT_ERROR联合使用), MYSQLI_REPORT_ERROR (报告MYSQL错误)和 MYSQLI_REPORT_INDEX (报告索引相关的错误)的任意组合。 参阅<span class="function">mysqli_report.

mysqli_driver::embedded_server_end

mysqli_embedded_server_end

Stop embedded server

Warning

该函数已在 PHP 7.4.0 中 移除

说明

面向对象风格

public void mysqli_driver::embedded_server_end ( void )

过程化风格

void <span class="methodname">mysqli_embedded_server_end ( <span class="methodparam">void )

Warning

本函数还未编写文档,仅有参数列表。

mysqli_driver::embedded_server_start

mysqli_embedded_server_start

Initialize and start embedded server

Warning

该函数已在 PHP 7.4.0 中 移除

说明

面向对象风格

public bool mysqli_driver::embedded_server_start ( int $start , <span class="type">array $arguments , <span class="methodparam">array $groups )

过程化风格

bool <span class="methodname">mysqli_embedded_server_start ( <span class="methodparam">int $start , array $arguments , <span class="type">array $groups )

Warning

本函数还未编写文档,仅有参数列表。

mysqli_driver::$report_mode

mysqli_report

Enables or disables internal report functions

说明

面向对象风格

int$mysqli_driver->report_mode ;

过程化风格

bool <span class="methodname">mysqli_report ( <span class="methodparam">int $flags )

A function helpful in improving queries during code development and testing. Depending on the flags, it reports errors from mysqli function calls or queries that don't use an index (or use a bad index).

参数

flags
| Name | Description | |----------------------------|--------------------------------------------------------------------------------------------| | MYSQLI_REPORT_OFF | Turns reporting off (the default) | | MYSQLI_REPORT_ERROR | Report errors from mysqli function calls | | MYSQLI_REPORT_STRICT | Throw mysqli_sql_exception for errors instead of warnings | | MYSQLI_REPORT_INDEX | Report if no index or bad index was used in a query | | MYSQLI_REPORT_ALL | Set all options (report all) |

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 面向对象风格

<?php

$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* activate reporting */
$driver = new mysqli_driver();
$driver->report_mode = MYSQLI_REPORT_ALL;

try {

    /* this query should report an error */
    $result = $mysqli->query("SELECT Name FROM Nonexistingtable WHERE population > 50000");

    /* this query should report a bad index */
    $result = $mysqli->query("SELECT Name FROM City WHERE population > 50000");

    $result->close();

    $mysqli->close();

} catch (mysqli_sql_exception $e) {

    echo $e->__toString();
}
?>

示例 #2 过程化风格

<?php
/* activate reporting */
mysqli_report(MYSQLI_REPORT_ALL);

$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* this query should report an error */
$result = mysqli_query("SELECT Name FROM Nonexistingtable WHERE population > 50000");

/* this query should report a bad index */
$result = mysqli_query("SELECT Name FROM City WHERE population > 50000");

mysqli_free_result($result);

mysqli_close($link);
?>

参见

  • mysqli_debug
  • mysqli_dump_debug_info
  • mysqli_sql_exception
  • set_exception_handler
  • error_reporting

简介

表示一个 MySQL 警告。

类摘要

mysqli_warning

class mysqli_warning {

/* 属性 */

public $message ;

public $sqlstate ;

public $errno ;

/* 方法 */

public bool next ( <span class="methodparam">void )

}

属性

message
消息字符串

sqlstate
SQL状态

errno
错误编号

mysqli_warning::next

Fetch next warning

说明

public bool mysqli_warning::next ( <span class="methodparam">void )

Change warning information to the next warning if possible.

Once the warning has been set to the next warning, new values of properties message, sqlstate and errno of <span class="classname">mysqli_warning are available.

参数

此函数没有参数。

返回值

Returns true if next warning was fetched successfully. If there are no more warnings, it will return false

简介

mysqli异常类

类摘要

mysqli_sql_exception

class mysqli_sql_exception <span class="ooclass"> extends RuntimeException {

/* 属性 */

protected string $sqlstate ;

/* 继承的属性 */

protected string $message ;

protected int $code ;

protected string $file ;

protected int $line ;

}

属性

sqlstate
出现错误的sql状态

mysqli_connect

别名 mysqli::__construct

说明

此函数是该函数的别名: <span class="methodname">mysqli::__construct

虽然说在 mysqli::__construct 的文档 对 mysqli_connect 函数也进行了详细的说明, 这里依然给出一个简单的示例:

范例

示例 #1 mysqli_connect 例程

<?php
$link = mysqli_connect("127.0.0.1", "my_user", "my_password", "my_db");

if (!$link) {
    echo "Error: Unable to connect to MySQL." . PHP_EOL;
    echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;
    echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;
    exit;
}

echo "Success: A proper connection to MySQL was made! The my_db database is great." . PHP_EOL;
echo "Host information: " . mysqli_get_host_info($link) . PHP_EOL;

mysqli_close($link);
?>

以上例程的输出类似于:

Success: A proper connection to MySQL was made! The my_db database is great.
Host information: localhost via TCP/IP

mysqli_escape_string

别名 mysqli_real_escape_string

说明

此函数是该函数的别名: <span class="function">mysqli_real_escape_string.

mysqli_execute

mysqli_stmt_execute 的别名

说明

此函数是该函数的别名: 这个函数是 <span class="function">mysqli_stmt_execute 的一个别名。

注释

Note:

mysqli_execute 已经被废弃并且将会被移除。

参见

  • mysqli_stmt_execute

mysqli_get_client_stats

返回客户端进程统计信息

说明

array <span class="methodname">mysqli_get_client_stats ( <span class="methodparam">void )

返回客户端进程统计信息 仅可用于 mysqlnd

参数

返回值

如果成功,则返回一个数组包含客户端进程的统计信息,否则返回 false

范例

示例 #1 A mysqli_get_client_stats 例程

<?php
$link = mysqli_connect();
print_r(mysqli_get_client_stats());
?>

以上例程的输出类似于:

Array
(
    [bytes_sent] => 43
    [bytes_received] => 80
    [packets_sent] => 1
    [packets_received] => 2
    [protocol_overhead_in] => 8
    [protocol_overhead_out] => 4
    [bytes_received_ok_packet] => 11
    [bytes_received_eof_packet] => 0
    [bytes_received_rset_header_packet] => 0
    [bytes_received_rset_field_meta_packet] => 0
    [bytes_received_rset_row_packet] => 0
    [bytes_received_prepare_response_packet] => 0
    [bytes_received_change_user_packet] => 0
    [packets_sent_command] => 0
    [packets_received_ok] => 1
    [packets_received_eof] => 0
    [packets_received_rset_header] => 0
    [packets_received_rset_field_meta] => 0
    [packets_received_rset_row] => 0
    [packets_received_prepare_response] => 0
    [packets_received_change_user] => 0
    [result_set_queries] => 0
    [non_result_set_queries] => 0
    [no_index_used] => 0
    [bad_index_used] => 0
    [slow_queries] => 0
    [buffered_sets] => 0
    [unbuffered_sets] => 0
    [ps_buffered_sets] => 0
    [ps_unbuffered_sets] => 0
    [flushed_normal_sets] => 0
    [flushed_ps_sets] => 0
    [ps_prepared_never_executed] => 0
    [ps_prepared_once_executed] => 0
    [rows_fetched_from_server_normal] => 0
    [rows_fetched_from_server_ps] => 0
    [rows_buffered_from_client_normal] => 0
    [rows_buffered_from_client_ps] => 0
    [rows_fetched_from_client_normal_buffered] => 0
    [rows_fetched_from_client_normal_unbuffered] => 0
    [rows_fetched_from_client_ps_buffered] => 0
    [rows_fetched_from_client_ps_unbuffered] => 0
    [rows_fetched_from_client_ps_cursor] => 0
    [rows_skipped_normal] => 0
    [rows_skipped_ps] => 0
    [copy_on_write_saved] => 0
    [copy_on_write_performed] => 0
    [command_buffer_too_small] => 0
    [connect_success] => 1
    [connect_failure] => 0
    [connection_reused] => 0
    [reconnect] => 0
    [pconnect_success] => 0
    [active_connections] => 1
    [active_persistent_connections] => 0
    [explicit_close] => 0
    [implicit_close] => 0
    [disconnect_close] => 0
    [in_middle_of_command_close] => 0
    [explicit_free_result] => 0
    [implicit_free_result] => 0
    [explicit_stmt_close] => 0
    [implicit_stmt_close] => 0
    [mem_emalloc_count] => 0
    [mem_emalloc_ammount] => 0
    [mem_ecalloc_count] => 0
    [mem_ecalloc_ammount] => 0
    [mem_erealloc_count] => 0
    [mem_erealloc_ammount] => 0
    [mem_efree_count] => 0
    [mem_malloc_count] => 0
    [mem_malloc_ammount] => 0
    [mem_calloc_count] => 0
    [mem_calloc_ammount] => 0
    [mem_realloc_count] => 0
    [mem_realloc_ammount] => 0
    [mem_free_count] => 0
    [proto_text_fetched_null] => 0
    [proto_text_fetched_bit] => 0
    [proto_text_fetched_tinyint] => 0
    [proto_text_fetched_short] => 0
    [proto_text_fetched_int24] => 0
    [proto_text_fetched_int] => 0
    [proto_text_fetched_bigint] => 0
    [proto_text_fetched_decimal] => 0
    [proto_text_fetched_float] => 0
    [proto_text_fetched_double] => 0
    [proto_text_fetched_date] => 0
    [proto_text_fetched_year] => 0
    [proto_text_fetched_time] => 0
    [proto_text_fetched_datetime] => 0
    [proto_text_fetched_timestamp] => 0
    [proto_text_fetched_string] => 0
    [proto_text_fetched_blob] => 0
    [proto_text_fetched_enum] => 0
    [proto_text_fetched_set] => 0
    [proto_text_fetched_geometry] => 0
    [proto_text_fetched_other] => 0
    [proto_binary_fetched_null] => 0
    [proto_binary_fetched_bit] => 0
    [proto_binary_fetched_tinyint] => 0
    [proto_binary_fetched_short] => 0
    [proto_binary_fetched_int24] => 0
    [proto_binary_fetched_int] => 0
    [proto_binary_fetched_bigint] => 0
    [proto_binary_fetched_decimal] => 0
    [proto_binary_fetched_float] => 0
    [proto_binary_fetched_double] => 0
    [proto_binary_fetched_date] => 0
    [proto_binary_fetched_year] => 0
    [proto_binary_fetched_time] => 0
    [proto_binary_fetched_datetime] => 0
    [proto_binary_fetched_timestamp] => 0
    [proto_binary_fetched_string] => 0
    [proto_binary_fetched_blob] => 0
    [proto_binary_fetched_enum] => 0
    [proto_binary_fetched_set] => 0
    [proto_binary_fetched_geometry] => 0
    [proto_binary_fetched_other] => 0
)

参见

mysqli_get_links_stats

返回打开和缓存的链接相关信息

说明

array <span class="methodname">mysqli_get_links_stats ( <span class="methodparam">void )

mysqli_get_links_stats 返回已经打开和缓存的MySQL链接的相关信息。

参数

此函数没有参数。

返回值

mysqli_get_links_stats 返回一个有三个元素的关联数组, 键如下:

total
类型 integer 所有状态链接的总数

active_plinks
类型 integer 不活跃的持久链接数

cached_plinks
类型 integer 不活跃的持久链接数

mysqli_report

别名 mysqli_driver->report_mode

说明

此函数是该函数的别名: mysqli_driver->report_mode

mysqli::set_opt

mysqli_set_opt

Alias of mysqli_options

说明

此函数是该函数的别名: 这个函数是 <span class="function">mysqli_options 的一个别名。

目录

Mysql_xdevapi

目录

This extension provides access to the MySQL Document Store via the X DevAPI. The X DevAPI is a common API provided by multiple MySQL Connectors providing easy access to relational tables as well as collections of documents, which are represented in JSON, from a API with CRUD-style operations.

The X DevAPI uses the X Protocol, the new generation client-server protocol of the MySQL 8.0 server.

For general information about the MySQL Document Store, please refer to the » MySQL Document Store chapter in the MySQL manual.

安装/配置

目录

需求

This extension requires a MySQL 8+ server with the X plugin enabled (default).

Prerequisite libraries for compiling this extension are: Boost (1.53.0 or higher), OpenSSL, and Protobuf.

安装

» PECL 扩展未与 PHP 捆绑。

An example installation procedure on Ubuntu 18.04 with PHP 7.2:

// Dependencies
$ apt install build-essential libprotobuf-dev libboost-dev openssl protobuf-compiler liblz4-tool zstd

// PHP with the desired extensions; php7.2-dev is required to compile
$ apt install php7.2-cli php7.2-dev php7.2-mysql php7.2-pdo php7.2-xml

// Compile the extension
$ pecl install mysql_xdevapi

The pecl install command does not enable PHP extensions (by default) and enabling PHP extensions can be done in several ways. Another PHP 7.2 on Ubuntu 18.04 example:

// Create its own ini file
$ echo "extension=mysql_xdevapi.so" > /etc/php/7.2/mods-available/mysql_xdevapi.ini

// Use the 'phpenmod' command (note: it's Debian/Ubuntu specific)
$ phpenmod -v 7.2 -s ALL mysql_xdevapi

// A 'phpenmod' alternative is to manually symlink it
// $ ln -s /etc/php/7.2/mods-available/mysql_xdevapi.ini /etc/php/7.2/cli/conf.d/20-mysql_xdevapi.ini

// Let's see which MySQL extensions are enabled now
$ php -m |grep mysql

mysql_xdevapi
mysqli
mysqlnd
pdo_mysql

安装此 PECL 扩展相关的信息可在手册中标题为 PECL 扩展的安装章节中找到。更多信息如新的发行版本、下载、源文件、 维护人员信息及变更日志等,都在此处: » https://pecl.php.net/package/mysql_xdevapi.

运行时配置

这些函数的行为受 php.ini 中的设置影响。

名字 默认 可修改范围 更新日志
xmysqlnd.collect_memory_statistics 0 PHP_INI_SYSTEM
xmysqlnd.collect_statistics 1 PHP_INI_ALL
xmysqlnd.debug   PHP_INI_SYSTEM
xmysqlnd.mempool_default_size 16000 PHP_INI_ALL
xmysqlnd.net_read_timeout 31536000 PHP_INI_SYSTEM
xmysqlnd.trace_alloc   PHP_INI_SYSTEM

这是配置指令的简短说明。

xmysqlnd.collect_memory_statistics int

xmysqlnd.collect_statistics int

xmysqlnd.debug string

xmysqlnd.mempool_default_size int

xmysqlnd.net_read_timeout int

xmysqlnd.trace_alloc string

Building / Compiling From Source

Considerations for compiling this extension from source.

  • The extension name is 'mysql_xdevapi', so use --enable-mysql-xdevapi.

  • Boost: required, optionally use the --with-boost=DIR configure option or set the MYSQL_XDEVAPI_BOOST_ROOT environment variable. Only the boost header files are required; not the binaries.

  • Google Protocol Buffers (protobuf): required, optionally use the --with-protobuf=DIR configure option or set the MYSQL_XDEVAPI_PROTOBUF_ROOT environment variable.

    Optionally use make protobufs to generate protobuf files (*.pb.cc/.h), and make clean-protobufs to delete generate protobuf files.

    Windows specific protobuf note: depending on your environment, the static library with a multi-threaded DLL runtime may be needed. To prepare, use the following options: -Dprotobuf_MSVC_STATIC_RUNTIME=OFF -Dprotobuf_BUILD_SHARED_LIBS=OFF

  • Google Protocol Buffers / protocol compiler (protoc): required, ensure that proper 'protoc' is available in the PATH while building. It is especially important as Windows PHP SDK batch scripts may overwrite the environment.

  • Bison: required, and available from the PATH.

    Windows specific bison note: we strongly recommended that bison delivered with the chosen PHP SDKis used else an error similar to "zend_globals_macros.h(39): error C2375: 'zendparse': redefinition; different linkage Zend/zend_language_parser.h(214): note: see declaration of 'zendparse'" may be the result. Also, Windows PHP SDK batch scripts may overwrite the environment.

  • Windows Specific Notes: To prepare the environment, see the official Windows build documentation for » the current SDK.

    We recommend using the backslash '\\' instead of a slash '/' for all paths.

预定义常量

下列常量由此扩展定义,且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

MYSQLX_CLIENT_SSL (int)

MYSQLX_TYPE_DECIMAL (int)

MYSQLX_TYPE_TINY (int)

MYSQLX_TYPE_SHORT (int)

MYSQLX_TYPE_SMALLINT (int)

MYSQLX_TYPE_MEDIUMINT (int)

MYSQLX_TYPE_INT (int)

MYSQLX_TYPE_BIGINT (int)

MYSQLX_TYPE_LONG (int)

MYSQLX_TYPE_FLOAT (int)

MYSQLX_TYPE_DOUBLE (int)

MYSQLX_TYPE_NULL (int)

MYSQLX_TYPE_TIMESTAMP (int)

MYSQLX_TYPE_LONGLONG (int)

MYSQLX_TYPE_INT24 (int)

MYSQLX_TYPE_DATE (int)

MYSQLX_TYPE_TIME (int)

MYSQLX_TYPE_DATETIME (int)

MYSQLX_TYPE_YEAR (int)

MYSQLX_TYPE_NEWDATE (int)

MYSQLX_TYPE_ENUM (int)

MYSQLX_TYPE_SET (int)

MYSQLX_TYPE_TINY_BLOB (int)

MYSQLX_TYPE_MEDIUM_BLOB (int)

MYSQLX_TYPE_LONG_BLOB (int)

MYSQLX_TYPE_BLOB (int)

MYSQLX_TYPE_VAR_STRING (int)

MYSQLX_TYPE_STRING (int)

MYSQLX_TYPE_CHAR (int)

MYSQLX_TYPE_BYTES (int)

MYSQLX_TYPE_INTERVAL (int)

MYSQLX_TYPE_GEOMETRY (int)

MYSQLX_TYPE_JSON (int)

MYSQLX_TYPE_NEWDECIMAL (int)

MYSQLX_TYPE_BIT (int)

MYSQLX_LOCK_DEFAULT (int)

MYSQLX_LOCK_NOWAIT (int)

MYSQLX_LOCK_SKIP_LOCKED (int)

范例

The central entry point to the X DevAPI is the <span class="function">mysql_xdevapi\getSession function, which receives a URI to a MySQL 8.0 Server and returns a <span class="classname">mysql_xdevap\Session object.

示例 #1 Connecting to a MySQL Server

<?php
try {
    $session = mysql_xdevapi\getSession("mysqlx://user:password@host");
} catch(Exception $e) {
    die("Connection could not be established: " . $e->getMessage());
}

// ... use $session
?>

The session provides full access to the API. For a new MySQL Server installation, the first step is to create a database schema with a collection to store data:

示例 #2 Creating a Schema and Collection on the MySQL Server

<?php
$schema = $session->createSchema("test");
$collection = $schema->createCollection("example");
?>

When storing data, typically json_encode is used to encode the data into JSON, which can then be stored inside a collection.

The following example stores data into the collection we created earlier, and then retrieve parts of it again.

示例 #3 Storing and Retrieving Data

<?php
$marco = [
  "name" => "Marco",
  "age"  => 19,
  "job"  => "Programmer"
];
$mike = [
  "name" => "Mike",
  "age"  => 39,
  "job"  => "Manager"
];

$schema = $session->getSchema("test");
$collection = $schema->getCollection("example");

$collection->add($marco, $mike)->execute();

var_dump($collection->find("name = 'Mike'")->execute()->fetchOne());
?>

以上例程的输出类似于:

array(4) {
  ["_id"]=>
  string(28) "00005ad66aaf0000000000000003"
  ["age"]=>
  int(39)
  ["job"]=>
  string(7) "Manager"
  ["name"]=>
  string(4) "Mike"
}

The example demonstrates that the MySQL Server adds an extra field named _id, which serves as primary key to the document.

The example also demonstrates that retrieved data is sorted alphabetically. That specific order comes from the efficient binary storage inside the MySQL server, but it should not be relied upon. Refer to the MySQL JSON datatype documentation for details.

Optionally use PHP's iterators fetch multiple documents:

示例 #4 Fetching and Iterating Multiple Documents

<?php
$result = $collection->find()->execute();
foreach ($result as $doc) {
  echo "${doc["name"]} is a ${doc["job"]}.\n";
}
?>

以上例程的输出类似于:

Marco is a Programmer.
Mike is a Manager.

expression

Bind prepared statement variables as parameters

说明

object <span class="methodname">mysql_xdevapi\expression ( <span class="methodparam">string $expression )

Warning

本函数还未编写文档,仅有参数列表。

参数

expression

返回值

范例

示例 #1 mysql_xdevapi\Expression example

<?php
$expression = mysql_xdevapi\Expression("[age,job]");

$res  = $coll->find("age > 30")->fields($expression)->limit(3)->execute();
$data = $res->fetchAll();

print_r($data);
?>

以上例程的输出类似于:

<?php

getSession

Connect to a MySQL server

说明

mysql_xdevapi\Session <span class="methodname">mysql_xdevapi\getSession ( <span class="methodparam">string $uri )

Connects to the MySQL server.

参数

uri
The URI to the MySQL server, such as mysqlx://user:password@host.

URI format:

scheme://[user[:[password]]@]target[:port][?attribute1=value1&attribute2=value2...

  • scheme: required, the connection protocol

    In mysql_xdevapi it is always 'mysqlx' (for X Protocol)

  • user: optional, the MySQL user account for authentication

  • password: optional, the MySQL user's password for authentication

  • target: required, the server instance the connection refers to:

    * TCP connection (host name, IPv4 address, or IPv6 address)

    * Unix socket path (local file path)

    * Windows named-pipe (local file path)

  • port: optional, network port of MySQL server.

    by default port for X Protocol is 33060

  • ?attribute=value: this element is optional and specifies a data dictionary that contains different options, including:

    • The auth (authentication mechanism) attribute as it relates to encrypted connections. For additional information, see » Command Options for Encrypted Connections. The following 'auth' values are supported: plain, mysql41, external, and sha256_mem.

    • The connect-timeout attribute affects the connection and not subsequent operations. It is set per connection whether on a single or multiple hosts.

      Pass in a positive integer to define the connection timeout in seconds, or pass in 0 (zero) to disable the timeout (infinite). Not defining connect-timeout uses the default value of 10.

      Related, the MYSQLX_CONNECTION_TIMEOUT (timeout in seconds) and MYSQLX_TEST_CONNECTION_TIMEOUT (used while running tests) environment variables can be set and used instead of connect-timeout in the URI. The connect-timeout URI option has precedence over these environment variables.

    • The optional compression attribute accepts these values: preferred (client negotiates with server to find a supported algorithm; connection is uncompressed if a mutually supported algorithm is not found), required (like "preferred", but connection is terminated if a mutually supported algorithm is not found), or disabled (connection is uncompressed). Defaults to preferred.

      This option was added in version 8.0.20.

    • The optional compression-algorithms attribute defines the desired compression algorithms (and their preferred usage order): zstd_stream (alias: zstd), lz4_message (alias: lz4), or deflate_stream (aliases: deflate or zlib). By default, the order used (depending on system availability) is lz4_message, zstd_stream, then deflate_stream. For example, passing in compression-algorithms=[lz4,zstd_stream] uses lz4 if it's available, otherwise zstd_stream is used. If both are unavailable then behavior depends on the compression value e.g., if compression=required then it'll fail with an error.

      This option was added in version 8.0.22.

示例 #1 URI examples

mysqlx://foobar
mysqlx://root@localhost?socket=%2Ftmp%2Fmysqld.sock%2F
mysqlx://foo:bar@localhost:33060
mysqlx://foo:bar@localhost:33160?ssl-mode=disabled
mysqlx://foo:bar@localhost:33260?ssl-mode=required
mysqlx://foo:bar@localhost:33360?ssl-mode=required&auth=mysql41
mysqlx://foo:bar@(/path/to/socket)
mysqlx://foo:bar@(/path/to/socket)?auth=sha256_mem
mysqlx://foo:bar@[localhost:33060, 127.0.0.1:33061]
mysqlx://foobar?ssl-ca=(/path/to/ca.pem)&ssl-crl=(/path/to/crl.pem)
mysqlx://foo:bar@[localhost:33060, 127.0.0.1:33061]?ssl-mode=disabled
mysqlx://foo:bar@localhost:33160/?connect-timeout=0
mysqlx://foo:bar@localhost:33160/?connect-timeout=10&compression=required
mysqlx://foo:bar@localhost:33160/?connect-timeout=10&compression=required&compression-algorithms=[lz4,zstd_stream]

For related information, see MySQL Shell's » Connecting using a URI String.

返回值

A Session object.

错误/异常

A connection failure throws an Exception.

范例

示例 #2 mysql_xdevapi\getSession example

<?php
try {
    $session = mysql_xdevapi\getSession("mysqlx://user:password@host");
} catch(Exception $e) {
    die("Connection could not be established: " . $e->getMessage());
}

$schemas = $session->getSchemas();
print_r($schemas);

$mysql_version = $session->getServerVersion();
print_r($mysql_version);

var_dump($collection->find("name = 'Alfred'")->execute()->fetchOne());
?>

以上例程的输出类似于:

Array
(
    [0] => mysql_xdevapi\Schema Object
        (
            [name] => helloworld
        )
    [1] => mysql_xdevapi\Schema Object
        (
            [name] => information_schema
        )
    [2] => mysql_xdevapi\Schema Object
        (
            [name] => mysql
        )
    [3] => mysql_xdevapi\Schema Object
        (
            [name] => performance_schema
        )
    [4] => mysql_xdevapi\Schema Object
        (
            [name] => sys
        )
)

80012

array(4) {
  ["_id"]=>
  string(28) "00005ad66abf0001000400000003"
  ["age"]=>
  int(42)
  ["job"]=>
  string(7) "Butler"
  ["name"]=>
  string(4) "Alfred"
}

目录

  • expression — Bind prepared statement variables as parameters
  • getSession — Connect to a MySQL server

简介

类摘要

mysql_xdevapi\BaseResult

class mysql_xdevapi\BaseResult {

/* 方法 */

abstract <span class="modifier">public array <span class="methodname">getWarnings ( <span class="methodparam">void )

abstract <span class="modifier">public int <span class="methodname">getWarningsCount ( <span class="methodparam">void )

}

BaseResult::getWarnings

Fetch warnings from last operation

说明

abstract <span class="modifier">public array <span class="methodname">mysql_xdevapi\BaseResult::getWarnings ( void )

Fetches warnings generated by MySQL server's last operation.

参数

此函数没有参数。

返回值

An array of Warning objects from the last operation. Each object defines an error 'message', error 'level', and error 'code'. An empty array is returned if no errors are present.

范例

示例 #1 <span class="function">mysql_xdevapi\RowResult::getWarnings example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("CREATE DATABASE foo")->execute();
$session->sql("CREATE TABLE foo.test_table(x int)")->execute();

$schema = $session->getSchema("foo");
$table  = $schema->getTable("test_table");

$table->insert(['x'])->values([1])->values([2])->execute();

$res = $table->select(['x/0 as bad_x'])->execute();
$warnings = $res->getWarnings();

print_r($warnings);
?>

以上例程的输出类似于:

Array
(
    [0] => mysql_xdevapi\Warning Object
        (
            [message] => Division by 0
            [level] => 2
            [code] => 1365
        )
    [1] => mysql_xdevapi\Warning Object
        (
            [message] => Division by 0
            [level] => 2
            [code] => 1365
        )
)

BaseResult::getWarningsCount

Fetch warning count from last operation

说明

abstract <span class="modifier">public int <span class="methodname">mysql_xdevapi\BaseResult::getWarningsCount ( void )

Returns the number of warnings raised by the last operation. Specifically, these warnings are raised by the MySQL server.

参数

此函数没有参数。

返回值

The number of warnings from the last operation.

范例

示例 #1 <span class="function">mysql_xdevapi\RowResult::getWarningsCount example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS foo")->execute();
$session->sql("CREATE DATABASE foo")->execute();
$session->sql("CREATE TABLE foo.test_table(x int)")->execute();

$schema = $session->getSchema("foo");
$table  = $schema->getTable("test_table");

$table->insert(['x'])->values([1])->values([2])->execute();

$res = $table->select(['x/0 as bad_x'])->execute();

echo $res->getWarningsCount();
?>

以上例程的输出类似于:

2

简介

Provides access to the connection pool.

类摘要

mysql_xdevapi\Client

class mysql_xdevapi\Client {

/* 方法 */

public bool close ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\Session <span class="methodname">getSession ( <span class="methodparam">void )

}

mysql_xdevapi\Client::close

Close client

说明

public bool mysql_xdevapi\Client::close ( <span class="methodparam">void )

Close all client connections with the server.

参数

此函数没有参数。

返回值

true if connections are closed.

Client::__construct

Client constructor

说明

private <span class="methodname">mysql_xdevapi\Client::__construct ( <span class="methodparam">void )

Construct a client object.

参数

此函数没有参数。

范例

示例 #1 <span class="function">mysql_xdevapi\Client::__construct example

<?php
$pooling_options = '{
  "enabled": true,
    "maxSize": 10,
    "maxIdleTime": 3600,
    "queueTimeOut": 1000
}';
$client = mysql_xdevapi\getClient($connection_uri, $pooling_options);
$session = $client->getSession();

Client::getClient

Get client session

说明

public <span class="type">mysql_xdevapi\Session <span class="methodname">mysql_xdevapi\Client::getSession ( <span class="methodparam">void )

Get session associated with the client.

参数

此函数没有参数。

返回值

A Session object.

简介

类摘要

mysql_xdevapi\Collection

class mysql_xdevapi\Collection implements <span class="interfacename">mysql_xdevapi\SchemaObject {

/* 属性 */

public $name ;

/* 方法 */

public <span class="type">mysql_xdevapi\CollectionAdd <span class="methodname">add ( <span class="type">mixed $document )

public <span class="type">mysql_xdevapi\Result <span class="methodname">addOrReplaceOne ( <span class="methodparam">string $id , string $doc )

public int <span class="methodname">count ( void )

public void createIndex ( <span class="methodparam">string $index_name , <span class="type">string $index_desc_json )

public bool dropIndex ( <span class="methodparam">string $index_name )

public bool existsInDatabase ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">find ([ <span class="type">string $search_condition ] )

public string getName ( <span class="methodparam">void )

public Document getOne ( <span class="type">string $id )

public Schema Object getSchema ( <span class="methodparam">void )

public Session getSession ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">modify ( <span class="type">string $search_condition )

public <span class="type">mysql_xdevapi\CollectionRemove <span class="methodname">remove ( <span class="type">string $search_condition )

public <span class="type">mysql_xdevapi\Result <span class="methodname">removeOne ( <span class="type">string $id )

public <span class="type">mysql_xdevapi\Result <span class="methodname">replaceOne ( <span class="type">string $id , <span class="methodparam">string $doc )

}

属性

name

Collection::add

Add collection document

说明

public <span class="type">mysql_xdevapi\CollectionAdd <span class="methodname">mysql_xdevapi\Collection::add ( <span class="methodparam">mixed $document )

Triggers the insertion of the given document(s) into the collection, and multiple variants of this method are supported. Options include:

  1. Add a single document as a JSON string.

  2. Add a single document as an array as: [ 'field' => 'value', 'field2' => 'value2' ... ]

  3. A mix of both, and multiple documents can be added in the same operation.

参数

document
One or multiple documents, and this can be either JSON or an array of fields with their associated values. This cannot be an empty array.

The MySQL server automatically generates unique _id values for each document (recommended), although this can be manually added as well. This value must be unique as otherwise the add operation will fail.

返回值

A CollectionAdd object. Use execute() to return a Result that can be used to query the number of affected items, the number warnings generated by the operation, or to fetch a list of generated IDs for the inserted documents.

范例

示例 #1 mysql_xdevapi\Collection::add example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");

$collection = $schema->getCollection("people");

// Add two documents
$collection->add('{"name": "Fred",  "age": 21, "job": "Construction"}')->execute();
$collection->add('{"name": "Wilma", "age": 23, "job": "Teacher"}')->execute();

// Add two documents using a single JSON object
$result = $collection->add(
  '{"name": "Bernie",
    "jobs": [{"title":"Cat Herder","Salary":42000}, {"title":"Father","Salary":0}],
    "hobbies": ["Sports","Making cupcakes"]}',
  '{"name": "Jane",
    "jobs": [{"title":"Scientist","Salary":18000}, {"title":"Mother","Salary":0}],
    "hobbies": ["Walking","Making pies"]}')->execute();

// Fetch a list of generated ID's from the last add()
$ids = $result->getGeneratedIds();
print_r($ids);
?>

以上例程的输出类似于:

Array
(
    [0] => 00005b6b53610000000000000056
    [1] => 00005b6b53610000000000000057
)

注释

Note:

A unique _id is generated by MySQL Server 8.0 or higher, as demonstrated in the example. The _id field must be manually defined if using MySQL Server 5.7.

Collection::addOrReplaceOne

Add or replace collection document

说明

public <span class="type">mysql_xdevapi\Result <span class="methodname">mysql_xdevapi\Collection::addOrReplaceOne ( string $id , string $doc )

Add a new document, or replace a document if it already exists.

Here are several scenarios for this method:

  • If neither the id or any unique key values conflict with any document in the collection, then the document is added.

  • If the id does not match any document but one or more unique key values conflict with a document in the collection, then an error is raised.

  • If id matches an existing document and no unique keys are defined for the collection, then the document is replaced.

  • If id matches an existing document, and either all unique keys in the replacement document match that same document or they don't conflict with any other documents in the collection, then the document is replaced.

  • If id matches an existing document and one or more unique keys match a different document from the collection, then an error is raised.

参数

id
This is the filter id. If this id or any other field that has a unique index already exists in the collection, then it will update the matching document instead.

By default, this id is automatically generated by MySQL Server when the record was added, and is referenced as a field named '_id'.

doc
This is the document to add or replace, which is a JSON string.

返回值

A Result object.

范例

示例 #1 <span class="function">mysql_xdevapi\Collection::addOrReplaceOne example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");

$collection = $schema->getCollection("people");

// Using add()
$result = $collection->add('{"name": "Wilma", "age": 23, "job": "Teacher"}')->execute();

// Using addOrReplaceOne()
// Note: we're passing in a known _id value here
$result = $collection->addOrReplaceOne('00005b6b53610000000000000056', '{"name": "Fred",  "age": 21, "job": "Construction"}');

?>

Collection::__construct

Collection constructor

说明

private <span class="methodname">mysql_xdevapi\Collection::__construct ( void )

Construct a Collection object.

参数

此函数没有参数。

范例

示例 #1 <span class="function">mysql_xdevapi\Collection::getOne example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

$result = $collection->add('{"name": "Alfred", "age": 42, "job": "Butler"}')->execute();

// A unique _id is (by default, and recommended) generated by MySQL Server
// This retrieves the generated _id's; only one in this example, so $ids[0]
$ids        = $result->getGeneratedIds();
$alfreds_id = $ids[0];

// ...

print_r($alfreds_id);
print_r($collection->getOne($alfreds_id));
?>

以上例程的输出类似于:

00005b6b536100000000000000b1

Array
(
    [_id] => 00005b6b536100000000000000b1
    [age] => 42
    [job] => Butler
    [name] => Alfred
)

Collection::count

Get document count

说明

public int <span class="methodname">mysql_xdevapi\Collection::count ( <span class="methodparam">void )

This functionality is similar to a SELECT COUNT(*) SQL operation against the MySQL server for the current schema and collection. In other words, it counts the number of documents in the collection.

参数

此函数没有参数。

返回值

The number of documents in the collection.

范例

示例 #1 <span class="function">mysql_xdevapi\Collection::count example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");

$collection = $schema->getCollection("people");

$result = $collection
  ->add(
  '{"name": "Bernie",
    "jobs": [
      {"title":"Cat Herder","Salary":42000}, 
      {"title":"Father","Salary":0}
    ],
    "hobbies": ["Sports","Making cupcakes"]}',
  '{"name": "Jane",
    "jobs": [
      {"title":"Scientist","Salary":18000}, 
      {"title":"Mother","Salary":0}
    ],
    "hobbies": ["Walking","Making pies"]}')
  ->execute();

var_dump($collection->count());
?>

以上例程会输出:

int(2)

Collection::createIndex

Create collection index

说明

public void mysql_xdevapi\Collection::createIndex ( string $index_name , <span class="type">string $index_desc_json )

Creates an index on the collection.

An exception is thrown if an index with the same name already exists, or if index definition is not correctly formed.

参数

index_name
The name of the index that to create. This name must be a valid index name as accepted by the CREATE INDEX SQL query.

index_desc_json
Definition of the index to create. It contains an array of IndexField objects, and each object describes a single document member to include in the index, and an optional string for the type of index that might be INDEX (default) or SPATIAL.

A single IndexField description consists of the following fields:

  • field: string, the full document path to the document member or field to be indexed.

  • type: string, one of the supported SQL column types to map the field into. For numeric types, the optional UNSIGNED keyword may follow. For the TEXT type, the length to consider for indexing may be added.

  • required: bool, (optional) true if the field is required to exist in the document. Defaults to false, except for GEOJSON where it defaults to true.

  • options: integer, (optional) special option flags for use when decoding GEOJSON data.

  • srid: integer, (optional) srid value for use when decoding GEOJSON data.

It is an error to include other fields not described above in IndexDefinition or IndexField documents.

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\Collection::createIndex example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

// Creating a text index
$collection->createIndex(
  'myindex1', 
  '{"fields": [{
    "field": "$.name", 
    "type": "TEXT(25)", 
    "required": true}], 
    "unique": false}'
);

// A spatial index
$collection->createIndex(
  'myindex2', 
  '{"fields": [{
    "field": "$.home", 
    "type": "GEOJSON", 
    "required": true}], 
    "type": "SPATIAL"}'
);

// Index with multiple fields
$collection->createIndex(
  'myindex3', 
  '{"fields": [
    {
      "field": "$.name",
      "type": "TEXT(20)",
      "required": true
    },
    {
      "field": "$.age",
      "type": "INTEGER"
    },
    {
      "field": "$.job",
      "type": "TEXT(30)",
      "required": false
    }
  ],
  "unique": true
  }'
);

Collection::dropIndex

Drop collection index

说明

public bool mysql_xdevapi\Collection::dropIndex ( string $index_name )

Drop a collection index.

This operation does not yield an error if the index does not exist, but false is returned in that case.

参数

index_name
Name of collection index to drop.

返回值

true if the DROP INDEX operation succeeded, otherwise false.

范例

示例 #1 <span class="function">mysql_xdevapi\Collection::dropIndex example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");

// ...

$collection = $schema->getCollection("people");

$collection->createIndex(
  'myindex', 
  '{"fields": [{"field": "$.name", "type": "TEXT(25)", "required": true}], "unique": false}'
);

// ...

if ($collection->dropIndex('myindex')) {
    echo 'An index named 'myindex' was found, and dropped.';
}
?>

以上例程会输出:

An index named 'myindex' was found, and dropped.

Collection::existsInDatabase

Check if collection exists in database

说明

public bool <span class="methodname">mysql_xdevapi\Collection::existsInDatabase ( void )

Checks if the Collection object refers to a collection in the database (schema).

参数

此函数没有参数。

返回值

Returns true if collection exists in the database, else false if it does not.

A table defined with two columns (doc and _id) is considered a collection, and a third _json_schema column as of MySQL 8.0.21. Adding an additional column means existsInDatabase() will no longer see it as a collection.

范例

示例 #1 <span class="function">mysql_xdevapi\Collection::existsInDatabase example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");

// ...

$collection = $schema->getCollection("people");

// ...

if (!$collection->existsInDatabase()) {
    echo "The collection no longer exists in the database named addressbook. What happened?";
}
?>

Collection::find

Search for document

说明

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">mysql_xdevapi\Collection::find ([ <span class="methodparam">string $search_condition ] )

Search a database collection for a document or set of documents. The found documents are returned as a CollectionFind object is to further modify or fetch results from.

参数

search_condition
Although optional, normally a condition is defined to limit the results to a subset of documents.

Multiple elements might build the condition and the syntax supports parameter binding. The expression used as search condition must be a valid SQL expression. If no search condition is provided (field empty) then find('true') is assumed.

返回值

A CollectionFind object to verify the operation, or fetch the found documents.

范例

示例 #1 <span class="function">mysql_xdevapi\Collection::find example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

$collection->add('{"name": "Alfred",     "age": 18, "job": "Butler"}')->execute();
$collection->add('{"name": "Bob",        "age": 19, "job": "Swimmer"}')->execute();
$collection->add('{"name": "Fred",       "age": 20, "job": "Construction"}')->execute();
$collection->add('{"name": "Wilma",      "age": 21, "job": "Teacher"}')->execute();
$collection->add('{"name": "Suki",       "age": 22, "job": "Teacher"}')->execute();

$find   = $collection->find('job LIKE :job AND age > :age');
$result = $find
  ->bind(['job' => 'Teacher', 'age' => 20])
  ->sort('age DESC')
  ->limit(2)            
  ->execute();

print_r($result->fetchAll());
?>

以上例程会输出:

Array
(
    [0] => Array
        (
            [_id] => 00005b6b536100000000000000a8
            [age] => 22
            [job] => Teacher
            [name] => Suki
        )
    [1] => Array
        (
            [_id] => 00005b6b536100000000000000a7
            [age] => 21
            [job] => Teacher
            [name] => Wilma
        )
)

Collection::getName

Get collection name

说明

public string mysql_xdevapi\Collection::getName ( void )

Retrieve the collection's name.

参数

此函数没有参数。

返回值

The collection name, as a string.

范例

示例 #1 <span class="function">mysql_xdevapi\Collection::getName example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");


// ...

var_dump($collection->getName());
?>

以上例程的输出类似于:

string(6) "people"

Collection::getOne

Get one document

说明

public Document mysql_xdevapi\Collection::getOne ( string $id )

Fetches one document from the collection.

This is a shortcut for: Collection.find("_id = :id").bind("id", id).execute().fetchOne();

参数

id
The document _id in the collection.

返回值

The collection object, or null if the _id does not match a document.

范例

示例 #1 <span class="function">mysql_xdevapi\Collection::getOne example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

$result = $collection->add('{"name": "Alfred", "age": 42, "job": "Butler"}')->execute();

// A unique _id is (by default, and recommended) generated by MySQL Server
// This retrieves the generated _id's; only one in this example, so $ids[0]
$ids        = $result->getGeneratedIds();
$alfreds_id = $ids[0];

// ...

print_r($alfreds_id);
print_r($collection->getOne($alfreds_id));
?>

以上例程的输出类似于:

00005b6b536100000000000000b1

Array
(
    [_id] => 00005b6b536100000000000000b1
    [age] => 42
    [job] => Butler
    [name] => Alfred
)

Collection::getSchema

Get schema object

说明

public Schema Object <span class="methodname">mysql_xdevapi\Collection::getSchema ( <span class="methodparam">void )

Retrieve the schema object that contains the collection.

参数

此函数没有参数。

返回值

The schema object on success, or null if the object cannot be retrieved for the given collection.

范例

示例 #1 <span class="function">mysql_xdevapi\Collection::getSchema example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

var_dump($collection->getSchema());
?>

以上例程的输出类似于:

object(mysql_xdevapi\Schema)#9 (1) {
  ["name"]=>
  string(11) "addressbook"
}

Collection::getSession

Get session object

说明

public Session mysql_xdevapi\Collection::getSession ( void )

Get a new Session object from the Collection object.

参数

此函数没有参数。

返回值

A Session object.

范例

示例 #1 <span class="function">mysql_xdevapi\Collection::getSession example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

// ...

$newsession = $collection->getSession();

var_dump($session);
var_dump($newsession);
?>

以上例程的输出类似于:

object(mysql_xdevapi\Session)#1 (0) {
}
object(mysql_xdevapi\Session)#4 (0) {
}

Collection::modify

Modify collection documents

说明

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">mysql_xdevapi\Collection::modify ( <span class="methodparam">string $search_condition )

Modify collections that meet specific search conditions. Multiple operations are allowed, and parameter binding is supported.

参数

search_condition
Must be a valid SQL expression used to match the documents to modify. This expression might be as simple as true, which matches all documents, or it might use functions and operators such as 'CAST(_id AS SIGNED) >= 10', 'age MOD 2 = 0 OR age MOD 3 = 0', or '_id IN ["2","5","7","10"]'.

返回值

If the operation is not executed, then the function will return a Modify object that can be used to add additional modify operations.

If the modify operation is executed, then the returned object will contain the result of the operation.

范例

示例 #1 <span class="function">mysql_xdevapi\Collection::modify example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

$collection->add('{"name": "Alfred", "age": 18, "job": "Butler"}')->execute();
$collection->add('{"name": "Bob",    "age": 19, "job": "Painter"}')->execute();

// Add two new jobs for all Painters: Artist and Crafter
$collection
  ->modify("job in ('Butler', 'Painter')")
  ->arrayAppend('job', 'Artist')
  ->arrayAppend('job', 'Crafter')
  ->execute();

// Remove the 'beer' field from all documents with the age 21
$collection
  ->modify('age < 21')
  ->unset(['beer'])
  ->execute();
?>

Collection::remove

Remove collection documents

说明

public <span class="type">mysql_xdevapi\CollectionRemove <span class="methodname">mysql_xdevapi\Collection::remove ( <span class="methodparam">string $search_condition )

Remove collections that meet specific search conditions. Multiple operations are allowed, and parameter binding is supported.

参数

search_condition
Must be a valid SQL expression used to match the documents to modify. This expression might be as simple as true, which matches all documents, or it might use functions and operators such as 'CAST(_id AS SIGNED) >= 10', 'age MOD 2 = 0 OR age MOD 3 = 0', or '_id IN ["2","5","7","10"]'.

返回值

If the operation is not executed, then the function will return a Remove object that can be used to add additional remove operations.

If the remove operation is executed, then the returned object will contain the result of the operation.

范例

示例 #1 <span class="function">mysql_xdevapi\Collection::remove example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

$collection->add('{"name": "Alfred", "age": 18, "job": "Butler"}')->execute();
$collection->add('{"name": "Bob",    "age": 19, "job": "Painter"}')->execute();

// Remove all painters
$collection
  ->remove("job in ('Painter')")
  ->execute();

// Remove the oldest butler
$collection
  ->remove("job in ('Butler')")
  ->sort('age desc')
  ->limit(1)
  ->execute();

// Remove record with lowest age
$collection
  ->remove('true')
  ->sort('age desc')
  ->limit(1)
  ->execute();
?>

Collection::removeOne

Remove one collection document

说明

public <span class="type">mysql_xdevapi\Result <span class="methodname">mysql_xdevapi\Collection::removeOne ( <span class="methodparam">string $id )

Remove one document from the collection with the correspending ID. This is a shortcut for Collection.remove("_id = :id").bind("id", id).execute().

参数

id
The ID of the collection document to remove. Typically this is the _id that was generated by MySQL Server when the record was added.

返回值

A Result object that can be used to query the number of affected items or the number warnings generated by the operation.

范例

示例 #1 <span class="function">mysql_xdevapi\Collection::removeOne example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

$result = $collection->add('{"name": "Alfred", "age": 18, "job": "Butler"}')->execute();

// Normally the _id is known by other means, 
// but for this example let's fetch the generated id and use it
$ids       = $result->getGeneratedIds();
$alfred_id = $ids[0];

$result = $collection->removeOne($alfred_id);

if(!$result->getAffectedItemsCount()) {
    echo "Alfred with id $alfred_id was not removed.";
} else {
    echo "Goodbye, Alfred, you can take _id $alfred_id with you.";
}
?>

以上例程的输出类似于:

Goodbye, Alfred, you can take _id 00005b6b536100000000000000cb with you.

Collection::replaceOne

Replace one collection document

说明

public <span class="type">mysql_xdevapi\Result <span class="methodname">mysql_xdevapi\Collection::replaceOne ( <span class="methodparam">string $id , string $doc )

Updates (or replaces) the document identified by ID, if it exists.

参数

id
ID of the document to replace or update. Typically this is the _id that was generated by MySQL Server when the record was added.

doc
Collection document to update or replace the document matching the id parameter.

This document can be either a document object or a valid JSON string describing the new document.

返回值

A Result object that can be used to query the number of affected items and the number warnings generated by the operation.

范例

示例 #1 <span class="function">mysql_xdevapi\Collection::replaceOne example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

$result = $collection->add('{"name": "Alfred", "age": 18, "job": "Butler"}')->execute();

// Normally the _id is known by other means, 
// but for this example let's fetch the generated id and use it
$ids       = $result->getGeneratedIds();
$alfred_id = $ids[0];

// ...

$alfred = $collection->getOne($alfred_id);
$alfred['age'] = 81;
$alfred['job'] = 'Guru';

$collection->replaceOne($alfred_id, $alfred);

?>

简介

类摘要

mysql_xdevapi\CollectionAdd

class mysql_xdevapi\CollectionAdd implements <span class="interfacename">mysql_xdevapi\Executable {

/* 方法 */

public <span class="type">mysql_xdevapi\Result <span class="methodname">execute ( <span class="methodparam">void )

}

CollectionAdd::__construct

CollectionAdd constructor

说明

private <span class="methodname">mysql_xdevapi\CollectionAdd::__construct ( void )

Use to add a document to a collection; called from a Collection object.

参数

此函数没有参数。

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionAdd::__construct example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");

$collection = $schema->getCollection("people");

// Add two documents
$collection
  ->add('{"name": "Fred",  "age": 21, "job": "Construction"}')
  ->execute();

$collection
  ->add('{"name": "Wilma", "age": 23, "job": "Teacher"}')
  ->execute();

// Add two documents using a single JSON object
$result = $collection
  ->add(
    '{"name": "Bernie",
      "jobs": [{"title":"Cat Herder","Salary":42000}, {"title":"Father","Salary":0}],
      "hobbies": ["Sports","Making cupcakes"]}',
    '{"name": "Jane",
      "jobs": [{"title":"Scientist","Salary":18000}, {"title":"Mother","Salary":0}],
      "hobbies": ["Walking","Making pies"]}')
  ->execute();

// Fetch a list of generated ID's from the last add()
$ids = $result->getGeneratedIds();
print_r($ids);

?>

以上例程的输出类似于:

Array
(
    [0] => 00005b6b53610000000000000056
    [1] => 00005b6b53610000000000000057
)

注释

Note:

A unique _id is generated by MySQL Server 8.0 or higher, as demonstrated in the example. The _id field must be manually defined if using MySQL Server 5.7.

CollectionAdd::execute

Execute the statement

说明

public <span class="type">mysql_xdevapi\Result <span class="methodname">mysql_xdevapi\CollectionAdd::execute ( <span class="methodparam">void )

The execute method is required to send the CRUD operation request to the MySQL server.

参数

此函数没有参数。

返回值

A Result object that can be used to verify the status of the operation, such as the number of affected rows.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionAdd::execute example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");

$collection = $schema->getCollection("people");

// Add two documents
$collection
  ->add('{"name": "Fred",  "age": 21, "job": "Construction"}')
  ->execute();

$collection
  ->add('{"name": "Wilma", "age": 23, "job": "Teacher"}')
  ->execute();

// Add two documents using a single JSON object
$result = $collection
  ->add(
    '{"name": "Bernie",
      "jobs": [{"title":"Cat Herder","Salary":42000}, {"title":"Father","Salary":0}],
      "hobbies": ["Sports","Making cupcakes"]}',
    '{"name": "Jane",
      "jobs": [{"title":"Scientist","Salary":18000}, {"title":"Mother","Salary":0}],
      "hobbies": ["Walking","Making pies"]}')
  ->execute();

// Fetch a list of generated ID's from the last add()
$ids = $result->getGeneratedIds();
print_r($ids);
?>

以上例程的输出类似于:

Array
(
    [0] => 00005b6b53610000000000000056
    [1] => 00005b6b53610000000000000057
)

简介

类摘要

mysql_xdevapi\CollectionFind

class mysql_xdevapi\CollectionFind implements <span class="interfacename">mysql_xdevapi\Executable <span class="oointerface">, <span class="interfacename">mysql_xdevapi\CrudOperationBindable , <span class="interfacename">mysql_xdevapi\CrudOperationLimitable , <span class="interfacename">mysql_xdevapi\CrudOperationSortable {

/* 方法 */

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">bind ( <span class="type">array $placeholder_values )

public <span class="type">mysql_xdevapi\DocResult <span class="methodname">execute ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">fields ( <span class="type">string $projection )

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">groupBy ( <span class="type">string $sort_expr )

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">having ( <span class="type">string $sort_expr )

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">limit ( <span class="type">int $rows )

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">lockExclusive ([ <span class="methodparam">int $lock_waiting_option ] )

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">lockShared ([ <span class="type">int $lock_waiting_option ] )

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">offset ( <span class="type">int $position )

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">sort ( <span class="type">string $sort_expr )

}

CollectionFind::bind

Bind value to query placeholder

说明

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">mysql_xdevapi\CollectionFind::bind ( <span class="methodparam">array $placeholder_values )

It allows the user to bind a parameter to the placeholder in the search condition of the find operation. The placeholder has the form of :NAME where ':' is a common prefix that must always exists before any NAME, NAME is the actual name of the placeholder. The bind function accepts a list of placeholders if multiple entities have to be substituted in the search condition.

参数

placeholder_values
Values to substitute in the search condition; multiple values are allowed and are passed as an array where "PLACEHOLDER_NAME => PLACEHOLDER_VALUE".

返回值

A CollectionFind object, or chain with execute() to return a Result object.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionFind::bind example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");
$result = $create
  ->add('{"name": "Alfred", "age": 18, "job": "Butler"}')
  ->execute();

// ...

$collection = $schema->getCollection("people");

$result = $collection
  ->find('job like :job and age > :age')
  ->bind(['job' => 'Butler', 'age' => 16])
  ->execute();

var_dump($result->fetchAll());
?>

以上例程的输出类似于:

array(1) {
  [0]=>
  array(4) {
    ["_id"]=>
    string(28) "00005b6b536100000000000000cf"
    ["age"]=>
    int(18)
    ["job"]=>
    string(6) "Butler"
    ["name"]=>
    string(6) "Alfred"
  }
}

CollectionFind::__construct

CollectionFind constructor

说明

private <span class="methodname">mysql_xdevapi\CollectionFind::__construct ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

范例

示例 #1 CollectionFind example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");
$result = $create
  ->add('{"name": "Alfred", "age": 18, "job": "Butler"}')
  ->execute();

// ...

$collection = $schema->getCollection("people");

$result = $collection
  ->find('job like :job and age > :age')
  ->bind(['job' => 'Butler', 'age' => 16])
  ->execute();

var_dump($result->fetchAll());
?>

以上例程的输出类似于:

array(1) {
  [0]=>
  array(4) {
    ["_id"]=>
    string(28) "00005b6b536100000000000000cf"
    ["age"]=>
    int(18)
    ["job"]=>
    string(6) "Butler"
    ["name"]=>
    string(6) "Alfred"
  }
}

CollectionFind::execute

Execute the statement

说明

public <span class="type">mysql_xdevapi\DocResult <span class="methodname">mysql_xdevapi\CollectionFind::execute ( void )

Execute the find operation; this functionality allows for method chaining.

参数

此函数没有参数。

返回值

A DocResult object that to either fetch results from, or to query the status of the operation.

范例

示例 #1 CollectionFind example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");

$create
  ->add('{"name": "Alfred", "age": 18, "job": "Butler"}')
  ->execute();

// ...

$collection = $schema->getCollection("people");

$result = $collection
  ->find('job like :job and age > :age')
  ->bind(['job' => 'Butler', 'age' => 16])
  ->execute();

var_dump($result->fetchAll());
?>

以上例程的输出类似于:

array(1) {
  [0]=>
  array(4) {
    ["_id"]=>
    string(28) "00005b6b536100000000000000cf"
    ["age"]=>
    int(18)
    ["job"]=>
    string(6) "Butler"
    ["name"]=>
    string(6) "Alfred"
  }
}

CollectionFind::fields

Set document field filter

说明

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">mysql_xdevapi\CollectionFind::fields ( <span class="methodparam">string $projection )

Defined the columns for the query to return. If not defined then all columns are used.

参数

projection
Can either be a single string or an array of string, those strings are identifying the columns that have to be returned for each document that match the search condition.

返回值

A CollectionFind object that can be used for further processing.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionFind::fields example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");

$create
  ->add('{"name": "Alfred", "age": 18, "job": "Butler"}')
  ->execute();

// ...

$collection = $schema->getCollection("people");

$result = $collection
  ->find('job like :job and age > :age')
  ->bind(['job' => 'Butler', 'age' => 16])
  ->fields('name')
  ->execute();

var_dump($result->fetchAll());
?>

以上例程的输出类似于:

array(1) {
  [0]=>
  array(1) {
    ["name"]=>
    string(6) "Alfred"
  }
}

CollectionFind::groupBy

Set grouping criteria

说明

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">mysql_xdevapi\CollectionFind::groupBy ( string $sort_expr )

This function can be used to group the result-set by one more columns, frequently this is used with aggregate functions like COUNT,MAX,MIN,SUM etc.

参数

sort_expr
The columns or columns that have to be used for the group operation, this can either be a single string or an array of string arguments, one for each column.

返回值

A CollectionFind that can be used for further processing

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionFind::groupBy example

<?php

//Assuming $coll is a valid Collection object

//Extract all the documents from the Collection and group the results by the 'name' field
$res = $coll->find()->groupBy('name')->execute();

?>

CollectionFind::having

Set condition for aggregate functions

说明

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">mysql_xdevapi\CollectionFind::having ( <span class="methodparam">string $sort_expr )

This function can be used after the 'field' operation in order to make a selection on the documents to extract.

参数

sort_expr
This must be a valid SQL expression, the use of aggreate functions is allowed

返回值

CollectionFind object that can be used for further processing

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionFind::having example

<?php

//Assuming $coll is a valid Collection object

//Find all the documents for which the 'age' is greather than 40,
//Only the columns 'name' and 'age' are returned in the Result object
$res = $coll->find()->fields(['name','age'])->having('age > 40')->execute();

?>

CollectionFind::limit

Limit number of returned documents

说明

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">mysql_xdevapi\CollectionFind::limit ( <span class="methodparam">int $rows )

Set the maximum number of documents to return.

参数

rows
Maximum number of documents.

返回值

A CollectionFind object that can be used for additional processing; chain with the execute() method to return a DocResult object.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionFind::limit example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");
$create
  ->add('{"name": "Alfred", "age": 18, "job": "Butler"}')
  ->execute();
$create
  ->add('{"name": "Reginald", "age": 42, "job": "Butler"}')
  ->execute();


// ...

$collection = $schema->getCollection("people");

$result = $collection
  ->find('job like :job and age > :age')
  ->bind(['job' => 'Butler', 'age' => 16])
  ->sort('age desc')
  ->limit(1)
  ->execute();

var_dump($result->fetchAll());
?>

以上例程的输出类似于:

array(1) {
  [0]=>
  array(4) {
    ["_id"]=>
    string(28) "00005b6b536100000000000000f3"
    ["age"]=>
    int(42)
    ["job"]=>
    string(6) "Butler"
    ["name"]=>
    string(8) "Reginald"
  }
}

CollectionFind::lockExclusive

Execute operation with EXCLUSIVE LOCK

说明

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">mysql_xdevapi\CollectionFind::lockExclusive ([ int $lock_waiting_option ] )

Lock exclusively the document, other transactions are blocked from updating the document until the document is locked While the document is locked, other transactions are blocked from updating those docs, from doing SELECT ... LOCK IN SHARE MODE, or from reading the data in certain transaction isolation levels. Consistent reads ignore any locks set on the records that exist in the read view.

This feature is directly useful with the modify() command, to avoid concurrency problems. Basically, it serializes access to a row through row locking

参数

lock_waiting_option
Optional waiting option. By default it is MYSQLX_LOCK_DEFAULT. Valid values are these constants:

  • MYSQLX_LOCK_DEFAULT

  • MYSQLX_LOCK_NOWAIT

  • MYSQLX_LOCK_SKIP_LOCKED

返回值

Returns a CollectionFind object that can be used for further processing

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionFind::lockExclusive example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

$session->startTransaction();

$result = $collection
  ->find("age > 50")
  ->lockExclusive()
  ->execute();

// ... do an operation on the object

// Complete the transaction and unlock the document
$session->commit();
?>

CollectionFind::lockShared

Execute operation with SHARED LOCK

说明

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">mysql_xdevapi\CollectionFind::lockShared ([ int $lock_waiting_option ] )

Allows to share the documents between multiple transactions which are locking in shared mode.

Other sessions can read the rows, but cannot modify them until your transaction commits.

If any of these rows were changed by another transaction that has not yet committed,

your query waits until that transaction ends and then uses the latest values.

参数

lock_waiting_option
Optional waiting option. By default it is MYSQLX_LOCK_DEFAULT. Valid values are these constants:

  • MYSQLX_LOCK_DEFAULT

  • MYSQLX_LOCK_NOWAIT

  • MYSQLX_LOCK_SKIP_LOCKED

返回值

A CollectionFind object that can be used for further processing

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionFind::lockShared example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

$session->startTransaction();

$result = $collection
  ->find("age > 50")
  ->lockShared()
  ->execute();

// ... read the object in shared mode

// Complete the transaction and unlock the document
$session->commit();
?>

CollectionFind::offset

Skip given number of elements to be returned

说明

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">mysql_xdevapi\CollectionFind::offset ( <span class="methodparam">int $position )

Skip (offset) these number of elements that otherwise would be returned by the find operation. Use with the limit() method.

Defining an offset larger than the result set size results in an empty set.

参数

position
Number of elements to skip for the limit() operation.

返回值

A CollectionFind object that can be used for additional processing.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionFind::offset example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");
$create
  ->add('{"name": "Alfred", "age": 18, "job": "Butler"}')
  ->execute();
$create
  ->add('{"name": "Reginald", "age": 42, "job": "Butler"}')
  ->execute();

// ...

$collection = $schema->getCollection("people");

$result = $collection
  ->find()
  ->sort('age asc')
  ->offset(1)
  ->limit(1)
  ->execute();

var_dump($result->fetchAll());
?>

以上例程的输出类似于:

array(1) {
  [0]=>
  array(4) {
    ["_id"]=>
    string(28) "00005b6b536100000000000000f3"
    ["age"]=>
    int(42)
    ["job"]=>
    string(6) "Butler"
    ["name"]=>
    string(8) "Reginald"
  }
}

CollectionFind::sort

Set the sorting criteria

说明

public <span class="type">mysql_xdevapi\CollectionFind <span class="methodname">mysql_xdevapi\CollectionFind::sort ( <span class="methodparam">string $sort_expr )

Sort the result set by the field selected in the sort_expr argument. The allowed orders are ASC (Ascending) or DESC (Descending). This operation is equivalent to the 'ORDER BY' SQL operation and it follows the same set of rules.

参数

sort_expr
One or more sorting expressions can be provided. The evaluation is from left to right, and each expression is separated by a comma.

返回值

A CollectionFind object that can be used to execute the command, or to add additional operations.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionFind::sort example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");
$create
  ->add('{"name": "Alfred", "age": 18, "job": "Butler"}')
  ->execute();
$create
  ->add('{"name": "Reginald", "age": 42, "job": "Butler"}')
  ->execute();

// ...

$collection = $schema->getCollection("people");

$result = $collection
  ->find()
  ->sort('job desc', 'age asc')
  ->execute();

var_dump($result->fetchAll());
?>

以上例程的输出类似于:

array(2) {
  [0]=>
  array(4) {
    ["_id"]=>
    string(28) "00005b6b53610000000000000106"
    ["age"]=>
    int(18)
    ["job"]=>
    string(6) "Butler"
    ["name"]=>
    string(6) "Alfred"
  }
  [1]=>
  array(4) {
    ["_id"]=>
    string(28) "00005b6b53610000000000000107"
    ["age"]=>
    int(42)
    ["job"]=>
    string(6) "Butler"
    ["name"]=>
    string(8) "Reginald"
  }
}

简介

类摘要

mysql_xdevapi\CollectionModify

class mysql_xdevapi\CollectionModify implements <span class="interfacename">mysql_xdevapi\Executable <span class="oointerface">, <span class="interfacename">mysql_xdevapi\CrudOperationBindable , <span class="interfacename">mysql_xdevapi\CrudOperationLimitable , <span class="interfacename">mysql_xdevapi\CrudOperationSkippable , <span class="interfacename">mysql_xdevapi\CrudOperationSortable {

/* 方法 */

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">arrayAppend ( <span class="type">string $collection_field , <span class="methodparam">string $expression_or_literal )

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">arrayInsert ( <span class="type">string $collection_field , <span class="methodparam">string $expression_or_literal )

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">bind ( <span class="type">array $placeholder_values )

public <span class="type">mysql_xdevapi\Result <span class="methodname">execute ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">limit ( <span class="type">int $rows )

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">patch ( <span class="type">string $document )

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">replace ( <span class="type">string $collection_field , <span class="methodparam">string $expression_or_literal )

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">set ( <span class="type">string $collection_field , <span class="methodparam">string $expression_or_literal )

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">skip ( <span class="type">int $position )

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">sort ( <span class="type">string $sort_expr )

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">unset ( <span class="type">array $fields )

}

CollectionModify::arrayAppend

Append element to an array field

说明

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">mysql_xdevapi\CollectionModify::arrayAppend ( string $collection_field , <span class="type">string $expression_or_literal )

Add an element to a document's field, as multiple elements of a field are represented as an array. Unlike arrayInsert(), arrayAppend() always appends the new element at the end of the array, whereas arrayInsert() can define the location.

参数

collection_field
The identifier of the field where the new element is inserted.

expression_or_literal
The new element to insert at the end of the document field array.

返回值

A CollectionModify object that can be used to execute the command, or to add additional operations.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionModify::arrayAppend example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

$result = $collection
  ->add(
  '{"name":   "Bernie",
    "traits": ["Friend", "Brother", "Human"]}') 
  ->execute();

$collection
  ->modify("name in ('Bernie', 'Jane')")
  ->arrayAppend('traits', 'Happy')
  ->execute();

$result = $collection
  ->find()
  ->execute();

print_r($result->fetchAll());
?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [_id] => 00005b6b5361000000000000010c
            [name] => Bernie
            [traits] => Array
                (
                    [0] => Friend
                    [1] => Brother
                    [2] => Human
                    [3] => Happy
                )
        )
)

CollectionModify::arrayInsert

Insert element into an array field

说明

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">mysql_xdevapi\CollectionModify::arrayInsert ( string $collection_field , <span class="type">string $expression_or_literal )

Add an element to a document's field, as multiple elements of a field are represented as an array. Unlike arrayAppend(), arrayInsert() allows you to specify where the new element is inserted by defining which item it is after, whereas arrayAppend() always appends the new element at the end of the array.

参数

collection_field
Identify the item in the array that the new element is inserted after. The format of this parameter is FIELD_NAME[ INDEX ] where FIELD_NAME is the name of the document field to remove the element from, and INDEX is the INDEX of the element within the field.

The INDEX field is zero based, so the leftmost item from the array has an index of 0.

expression_or_literal
The new element to insert after FIELD_NAME[ INDEX ]

返回值

A CollectionModify object that can be used to execute the command, or to add additional operations

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionModify::arrayInsert example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

$result = $collection
  ->add(
  '{"name":   "Bernie",
    "traits": ["Friend", "Brother", "Human"]}') 
  ->execute();

$collection
  ->modify("name in ('Bernie', 'Jane')")
  ->arrayInsert('traits[1]', 'Happy')
  ->execute();

$result = $collection
  ->find()
  ->execute();

print_r($result->fetchAll());
?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [_id] => 00005b6b5361000000000000010d
            [name] => Bernie
            [traits] => Array
                (
                    [0] => Friend
                    [1] => Happy
                    [2] => Brother
                    [3] => Human
                )
        )
)

CollectionModify::bind

Bind value to query placeholder

说明

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">mysql_xdevapi\CollectionModify::bind ( <span class="methodparam">array $placeholder_values )

Bind a parameter to the placeholder in the search condition of the modify operation.

The placeholder has the form of :NAME where ':' is a common prefix that must always exists before any NAME where NAME is the name of the placeholder. The bind method accepts a list of placeholders if multiple entities have to be substituted in the search condition of the modify operation.

参数

placeholder_values
Placeholder values to substitute in the search condition. Multiple values are allowed and have to be passed as an array of mappings PLACEHOLDER_NAME->PLACEHOLDER_VALUE.

返回值

A CollectionModify object that can be used to execute the command, or to add additional operations.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionModify::bind example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

$result = $collection
  ->add(
  '{"name":   "Bernie",
    "traits": ["Friend", "Brother", "Human"]}') 
  ->execute();

$collection
  ->modify("name = :name")
  ->bind(['name' => 'Bernie'])
  ->arrayAppend('traits', 'Happy')
  ->execute();

$result = $collection
  ->find()
  ->execute();

print_r($result->fetchAll());
?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [_id] => 00005b6b53610000000000000110
            [name] => Bernie
            [traits] => Array
                (
                    [0] => Friend
                    [1] => Brother
                    [2] => Human
                    [3] => Happy
                )
        )
)

CollectionModify::__construct

CollectionModify constructor

说明

private <span class="methodname">mysql_xdevapi\CollectionModify::__construct ( void )

Modify (update) a collection, and is instantiated by the Collection::modify() method.

参数

此函数没有参数。

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionModify::__construct example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

$result = $collection
  ->add(
  '{"name":   "Bernie",
    "traits": ["Friend", "Brother", "Human"]}') 
  ->execute();

$collection
  ->modify("name in ('Bernie', 'Jane')")
  ->arrayAppend('traits', 'Happy')
  ->execute();

$result = $collection
  ->find()
  ->execute();

print_r($result->fetchAll());
?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [_id] => 00005b6b5361000000000000010c
            [name] => Bernie
            [traits] => Array
                (
                    [0] => Friend
                    [1] => Brother
                    [2] => Human
                    [3] => Happy
                )
        )
)

CollectionModify::execute

Execute modify operation

说明

public <span class="type">mysql_xdevapi\Result <span class="methodname">mysql_xdevapi\CollectionModify::execute ( void )

The execute method is required to send the CRUD operation request to the MySQL server.

参数

此函数没有参数。

返回值

A Result object that can be used to verify the status of the operation, such as the number of affected rows.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionModify::execute example

<?php

/* ... */

?>

CollectionModify::limit

Limit number of modified documents

说明

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">mysql_xdevapi\CollectionModify::limit ( int $rows )

Limit the number of documents modified by this operation. Optionally combine with skip() to define an offset value.

参数

rows
The maximum number of documents to modify.

返回值

A CollectionModify object.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionModify::limit example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

$collection->add('{"name": "Fred",  "age": 21, "job": "Construction"}')->execute();
$collection->add('{"name": "Wilma", "age": 23, "job": "Teacher"}')->execute();
$collection->add('{"name": "Betty", "age": 24, "job": "Teacher"}')->execute();

$collection
  ->modify("job = :job")
  ->bind(['job' => 'Teacher'])
  ->set('job', 'Principal')
  ->limit(1)
  ->execute();

$result = $collection
  ->find()
  ->execute();

print_r($result->fetchAll());
?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [_id] => 00005b6b53610000000000000118
            [age] => 21
            [job] => Construction
            [name] => Fred
        )
    [1] => Array
        (
            [_id] => 00005b6b53610000000000000119
            [age] => 23
            [job] => Principal
            [name] => Wilma
        )
    [2] => Array
        (
            [_id] => 00005b6b5361000000000000011a
            [age] => 24
            [job] => Teacher
            [name] => Betty
        )
)

CollectionModify::patch

Patch document

说明

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">mysql_xdevapi\CollectionModify::patch ( string $document )

Takes a patch object and applies it on one or more documents, and can update multiple document properties.

Warning

本函数还未编写文档,仅有参数列表。

参数

document
A document with the properties to apply to the matching documents.

返回值

A CollectionModify object.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionModify::patch example

<?php

$res = $coll->modify('"Programmatore" IN job')->patch('{"Hobby" : "Programmare"}')->execute();

?>

CollectionModify::replace

Replace document field

说明

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">mysql_xdevapi\CollectionModify::replace ( string $collection_field , <span class="type">string $expression_or_literal )

Replace (update) a given field value with a new one.

参数

collection_field
The document path of the item to set.

expression_or_literal
The value to set on the specified attribute.

返回值

A CollectionModify object.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionModify::replace example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

$result = $collection
  ->add(
  '{"name":   "Bernie",
    "traits": ["Friend", "Brother", "Human"]}') 
  ->execute();

$collection
  ->modify("name = :name")
  ->bind(['name' => 'Bernie'])
  ->replace("name", "Bern")
  ->execute();

$result = $collection
  ->find()
  ->execute();

print_r($result->fetchAll());
?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [_id] => 00005b6b5361000000000000011b
            [name] => Bern
            [traits] => Array
                (
                    [0] => Friend
                    [1] => Brother
                    [2] => Human
                )
        )
)

CollectionModify::set

Set document attribute

说明

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">mysql_xdevapi\CollectionModify::set ( <span class="methodparam">string $collection_field , <span class="type">string $expression_or_literal )

Sets or updates attributes on documents in a collection.

参数

collection_field
The document path (name) of the item to set.

expression_or_literal
The value to set it to.

返回值

A CollectionModify object.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionModify::set example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

$result = $collection
  ->add(
  '{"name":   "Bernie",
    "traits": ["Friend", "Brother", "Human"]}') 
  ->execute();

$collection
  ->modify("name = :name")
  ->bind(['name' => 'Bernie'])
  ->set("name", "Bern")
  ->execute();

$result = $collection
  ->find()
  ->execute();

print_r($result->fetchAll());
?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [_id] => 00005b6b53610000000000000111
            [name] => Bern
            [traits] => Array
                (
                    [0] => Friend
                    [1] => Brother
                    [2] => Human
                )
        )
)

CollectionModify::skip

Skip elements

说明

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">mysql_xdevapi\CollectionModify::skip ( <span class="methodparam">int $position )

Skip the first N elements that would otherwise be returned by a find operation. If the number of elements skipped is larger than the size of the result set, then the find operation returns an empty set.

Warning

本函数还未编写文档,仅有参数列表。

参数

position
Number of elements to skip.

返回值

A CollectionModify object to use for further processing.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionModify::skip example

<?php

$coll->modify('age > :age')->sort('age desc')->unset(['age'])->bind(['age' => 20])->limit(4)->skip(1)->execute();

?>

CollectionModify::sort

Set the sorting criteria

说明

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">mysql_xdevapi\CollectionModify::sort ( <span class="methodparam">string $sort_expr )

Sort the result set by the field selected in the sort_expr argument. The allowed orders are ASC (Ascending) or DESC (Descending). This operation is equivalent to the 'ORDER BY' SQL operation and it follows the same set of rules.

Warning

本函数还未编写文档,仅有参数列表。

参数

sort_expr
One or more sorting expression can be provided, the evaluation of these will be from the leftmost to the rightmost, each expression must be separated by a comma.

返回值

CollectionModify object that can be used for further processing.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionModify::sort example

<?php

$res = $coll->modify('true')->sort('name desc', 'age asc')->limit(4)->set('Married', 'NO')->execute();

?>

CollectionModify::unset

Unset the value of document fields

说明

public <span class="type">mysql_xdevapi\CollectionModify <span class="methodname">mysql_xdevapi\CollectionModify::unset ( array $fields )

Removes attributes from documents in a collection.

Warning

本函数还未编写文档,仅有参数列表。

参数

fields
The attributes to remove from documents in a collection.

返回值

CollectionModify object that can be used for further processing.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionModify::unset example

<?php

$res = $coll->modify('job like :job_name')->unset(["age", "name"])->bind(['job_name' => 'Plumber'])->execute();

?>

简介

类摘要

mysql_xdevapi\CollectionRemove

class mysql_xdevapi\CollectionRemove implements <span class="interfacename">mysql_xdevapi\Executable <span class="oointerface">, <span class="interfacename">mysql_xdevapi\CrudOperationBindable , <span class="interfacename">mysql_xdevapi\CrudOperationLimitable , <span class="interfacename">mysql_xdevapi\CrudOperationSortable {

/* 方法 */

public <span class="type">mysql_xdevapi\CollectionRemove <span class="methodname">bind ( <span class="type">array $placeholder_values )

public <span class="type">mysql_xdevapi\Result <span class="methodname">execute ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\CollectionRemove <span class="methodname">limit ( <span class="type">int $rows )

public <span class="type">mysql_xdevapi\CollectionRemove <span class="methodname">sort ( <span class="type">string $sort_expr )

}

CollectionRemove::bind

Bind value to placeholder

说明

public <span class="type">mysql_xdevapi\CollectionRemove <span class="methodname">mysql_xdevapi\CollectionRemove::bind ( <span class="methodparam">array $placeholder_values )

Bind a parameter to the placeholder in the search condition of the remove operation.

The placeholder has the form of :NAME where ':' is a common prefix that must always exists before any NAME where NAME is the name of the placeholder. The bind method accepts a list of placeholders if multiple entities have to be substituted in the search condition of the remove operation.

Warning

本函数还未编写文档,仅有参数列表。

参数

placeholder_values
Placeholder values to substitute in the search condition. Multiple values are allowed and have to be passed as an array of mappings PLACEHOLDER_NAME->PLACEHOLDER_VALUE.

返回值

A CollectionRemove object that can be used to execute the command, or to add additional operations.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionRemove::bind example

<?php

$res = $coll->remove('age > :age_from and age < :age_to')->bind(['age_from' => 20, 'age_to' => 50])->limit(7)->execute();

?>

CollectionRemove::__construct

CollectionRemove constructor

说明

private <span class="methodname">mysql_xdevapi\CollectionRemove::__construct ( void )

Remove collection documents, and is instantiated by the Collection::remove() method.

参数

此函数没有参数。

范例

示例 #1 <span class="function">mysql_xdevapi\Collection::remove example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("people");

$collection->add('{"name": "Alfred", "age": 18, "job": "Butler"}')->execute();
$collection->add('{"name": "Bob",    "age": 19, "job": "Painter"}')->execute();

// Remove all painters
$collection
  ->remove("job in ('Painter')")
  ->execute();

// Remove the oldest butler
$collection
  ->remove("job in ('Butler')")
  ->sort('age desc')
  ->limit(1)
  ->execute();

// Remove record with lowest age
$collection
  ->remove('true')
  ->sort('age desc')
  ->limit(1)
  ->execute();
?>

CollectionRemove::execute

Execute remove operation

说明

public <span class="type">mysql_xdevapi\Result <span class="methodname">mysql_xdevapi\CollectionRemove::execute ( void )

The execute function needs to be invoked in order to trigger the client to send the CRUD operation request to the server.

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

Result object.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionRemove::execute example

<?php

$res = $coll->remove('true')->sort('age desc')->limit(2)->execute();

?>

CollectionRemove::limit

Limit number of documents to remove

说明

public <span class="type">mysql_xdevapi\CollectionRemove <span class="methodname">mysql_xdevapi\CollectionRemove::limit ( int $rows )

Sets the maximum number of documents to remove.

Warning

本函数还未编写文档,仅有参数列表。

参数

rows
The maximum number of documents to remove.

返回值

Returns a CollectionRemove object that can be used to execute the command, or to add additional operations.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionRemove::limit example

<?php

$res = $coll->remove('job in (\'Barista\', \'Programmatore\', \'Ballerino\', \'Programmatrice\')')->limit(5)->sort(['age desc', 'name asc'])->execute();

?>

CollectionRemove::sort

Set the sorting criteria

说明

public <span class="type">mysql_xdevapi\CollectionRemove <span class="methodname">mysql_xdevapi\CollectionRemove::sort ( <span class="methodparam">string $sort_expr )

Sort the result set by the field selected in the sort_expr argument. The allowed orders are ASC (Ascending) or DESC (Descending). This operation is equivalent to the 'ORDER BY' SQL operation and it follows the same set of rules.

Warning

本函数还未编写文档,仅有参数列表。

参数

sort_expr
One or more sorting expressions can be provided. The evaluation is from left to right, and each expression is separated by a comma.

返回值

A CollectionRemove object that can be used to execute the command, or to add additional operations.

范例

示例 #1 <span class="function">mysql_xdevapi\CollectionRemove::sort example

<?php

$res = $coll->remove('true')->sort('age desc')->limit(2)->execute();

?>

简介

类摘要

mysql_xdevapi\ColumnResult

class mysql_xdevapi\ColumnResult {

/* 方法 */

public string getCharacterSetName ( <span class="methodparam">void )

public string getCollationName ( <span class="methodparam">void )

public string getColumnLabel ( <span class="methodparam">void )

public string getColumnName ( <span class="methodparam">void )

public int <span class="methodname">getFractionalDigits ( <span class="methodparam">void )

public int <span class="methodname">getLength ( <span class="methodparam">void )

public string getSchemaName ( <span class="methodparam">void )

public string getTableLabel ( <span class="methodparam">void )

public string getTableName ( <span class="methodparam">void )

public int <span class="methodname">getType ( <span class="methodparam">void )

public int <span class="methodname">isNumberSigned ( <span class="methodparam">void )

public int <span class="methodname">isPadded ( <span class="methodparam">void )

}

ColumnResult::__construct

ColumnResult constructor

说明

private <span class="methodname">mysql_xdevapi\ColumnResult::__construct ( void )

Retrieve column metadata, such as its character set; this is instantiated by the RowResult::getColumns() method.

参数

此函数没有参数。

范例

示例 #1 <span class="function">mysql_xdevapi\ColumnResult::__construct example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS nonsense")->execute();
$session->sql("CREATE DATABASE nonsense")->execute();
$session->sql("CREATE TABLE nonsense.numbers (hello int, world float unsigned)")->execute();
$session->sql("INSERT INTO  nonsense.numbers values (42, 42)")->execute();

$schema = $session->getSchema("nonsense");
$table  = $schema->getTable("numbers");

$result1 = $table->select('hello','world')->execute();

// Returns an array of ColumnResult objects
$columns = $result1->getColumns(); 

foreach ($columns as $column) {
    echo "\nColumn label " , $column->getColumnLabel();
    echo " is type "       , $column->getType();
    echo " and is ", ($column->isNumberSigned() === 0) ? "Unsigned." : "Signed.";
}

// Alternatively
$result2 = $session->sql("SELECT * FROM nonsense.numbers")->execute();

// Returns an array of FieldMetadata objects
print_r($result2->getColumns());

以上例程的输出类似于:

Column label hello is type 19 and is Signed.
Column label world is type 4  and is Unsigned.

Array
(
    [0] => mysql_xdevapi\FieldMetadata Object
        (
            [type] => 1
            [type_name] => SINT
            [name] => hello
            [original_name] => hello
            [table] => numbers
            [original_table] => numbers
            [schema] => nonsense
            [catalog] => def
            [collation] => 0
            [fractional_digits] => 0
            [length] => 11
            [flags] => 0
            [content_type] => 0
        )
    [1] => mysql_xdevapi\FieldMetadata Object
        (
            [type] => 6
            [type_name] => FLOAT
            [name] => world
            [original_name] => world
            [table] => numbers
            [original_table] => numbers
            [schema] => nonsense
            [catalog] => def
            [collation] => 0
            [fractional_digits] => 31
            [length] => 12
            [flags] => 1
            [content_type] => 0
        )
)

ColumnResult::getCharacterSetName

Get character set

说明

public string <span class="methodname">mysql_xdevapi\ColumnResult::getCharacterSetName ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\ColumnResult::getCharacterSetName example

<?php

/* ... */

?>

ColumnResult::getCollationName

Get collation name

说明

public string <span class="methodname">mysql_xdevapi\ColumnResult::getCollationName ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\ColumnResult::getCollationName example

<?php

/* ... */

?>

ColumnResult::getColumnLabel

Get column label

说明

public string <span class="methodname">mysql_xdevapi\ColumnResult::getColumnLabel ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\ColumnResult::getColumnLabel example

<?php

/* ... */

?>

ColumnResult::getColumnName

Get column name

说明

public string <span class="methodname">mysql_xdevapi\ColumnResult::getColumnName ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\ColumnResult::getColumnName example

<?php

/* ... */

?>

ColumnResult::getFractionalDigits

Get fractional digit length

说明

public int <span class="methodname">mysql_xdevapi\ColumnResult::getFractionalDigits ( void )

Fetch the number of fractional digits for column.

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\ColumnResult::getFractionalDigits example

<?php

/* ... */

?>

ColumnResult::getLength

Get column field length

说明

public int <span class="methodname">mysql_xdevapi\ColumnResult::getLength ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\ColumnResult::getLength example

<?php

/* ... */

?>

ColumnResult::getSchemaName

Get schema name

说明

public string <span class="methodname">mysql_xdevapi\ColumnResult::getSchemaName ( void )

Fetch the schema name where the column is stored.

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\ColumnResult::getSchemaName example

<?php

/* ... */

?>

ColumnResult::getTableLabel

Get table label

说明

public string <span class="methodname">mysql_xdevapi\ColumnResult::getTableLabel ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\ColumnResult::getTableLabel example

<?php

/* ... */

?>

ColumnResult::getTableName

Get table name

说明

public string <span class="methodname">mysql_xdevapi\ColumnResult::getTableName ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

Name of the table for the column.

范例

示例 #1 <span class="function">mysql_xdevapi\ColumnResult::getTableName example

<?php

/* ... */

?>

ColumnResult::getType

Get column type

说明

public int <span class="methodname">mysql_xdevapi\ColumnResult::getType ( <span class="methodparam">void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\ColumnResult::getType example

<?php

/* ... */

?>

ColumnResult::isNumberSigned

Check if signed type

说明

public int <span class="methodname">mysql_xdevapi\ColumnResult::isNumberSigned ( void )

Retrieve a table's column information, and is instantiated by the RowResult::getColumns() method.

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

true if a given column as a signed type.

范例

示例 #1 <span class="function">mysql_xdevapi\ColumnResult::isNumberSigned example

<?php

/* ... */

?>

ColumnResult::isPadded

Check if padded

说明

public int <span class="methodname">mysql_xdevapi\ColumnResult::isPadded ( <span class="methodparam">void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

true if a given column is padded.

范例

示例 #1 <span class="function">mysql_xdevapi\ColumnResult::isPadded example

<?php

/* ... */

?>

简介

类摘要

mysql_xdevapi\CrudOperationBindable

class mysql_xdevapi\CrudOperationBindable {

/* 方法 */

abstract <span class="modifier">public <span class="type">mysql_xdevapi\CrudOperationBindable <span class="methodname">bind ( <span class="type">array $placeholder_values )

}

CrudOperationBindable::bind

Bind value to placeholder

说明

abstract <span class="modifier">public <span class="type">mysql_xdevapi\CrudOperationBindable <span class="methodname">mysql_xdevapi\CrudOperationBindable::bind ( array $placeholder_values )

Binds a value to a specific placeholder.

Warning

本函数还未编写文档,仅有参数列表。

参数

placeholder_values
The name of the placeholders and the values to bind.

返回值

A CrudOperationBindable object.

范例

示例 #1 <span class="function">mysql_xdevapi\CrudOperationBindable::bind example

<?php

$res = $coll->modify('name like :name')->arrayInsert('job[0]', 'Calciatore')->bind(['name' => 'ENTITY'])->execute();
$res = $table->delete()->orderby('age desc')->where('age < 20 and age > 12 and name != :name')->bind(['name' => 'Tierney'])->limit(2)->execute();

?>

简介

类摘要

mysql_xdevapi\CrudOperationLimitable

class mysql_xdevapi\CrudOperationLimitable {

/* 方法 */

abstract <span class="modifier">public <span class="type">mysql_xdevapi\CrudOperationLimitable <span class="methodname">limit ( <span class="type">int $rows )

}

CrudOperationLimitable::limit

Set result limit

说明

abstract <span class="modifier">public <span class="type">mysql_xdevapi\CrudOperationLimitable <span class="methodname">mysql_xdevapi\CrudOperationLimitable::limit ( int $rows )

Sets the maximum number of records or documents to return.

Warning

本函数还未编写文档,仅有参数列表。

参数

rows
The maximum number of records or documents.

返回值

A CrudOperationLimitable object.

范例

示例 #1 <span class="function">mysql_xdevapi\CrudOperationLimitable::limit example

<?php

$res = $coll->find()->fields(['name as n','age as a','job as j'])->groupBy('j')->limit(11)->execute();
$res = $table->update()->set('age',69)->where('age > 15 and age < 22')->limit(4)->orderby(['age asc','name desc'])->execute();

?>

简介

类摘要

mysql_xdevapi\CrudOperationSkippable

class mysql_xdevapi\CrudOperationSkippable {

/* 方法 */

abstract <span class="modifier">public <span class="type">mysql_xdevapi\CrudOperationSkippable <span class="methodname">skip ( <span class="type">int $skip )

}

CrudOperationSkippable::skip

Number of operations to skip

说明

abstract <span class="modifier">public <span class="type">mysql_xdevapi\CrudOperationSkippable <span class="methodname">mysql_xdevapi\CrudOperationSkippable::skip ( int $skip )

Skip this number of records in the returned operation.

Warning

本函数还未编写文档,仅有参数列表。

参数

skip
Number of elements to skip.

返回值

A CrudOperationSkippable object.

范例

示例 #1 <span class="function">mysql_xdevapi\CrudOperationSkippable::skip example

<?php

$res = $coll->find('job like \'Programmatore\'')->limit(1)->skip(3)->sort('age asc')->execute();

?>

简介

类摘要

mysql_xdevapi\CrudOperationSortable

class mysql_xdevapi\CrudOperationSortable {

/* 方法 */

abstract <span class="modifier">public <span class="type">mysql_xdevapi\CrudOperationSortable <span class="methodname">sort ( <span class="type">string $sort_expr )

}

CrudOperationSortable::sort

Sort results

说明

abstract <span class="modifier">public <span class="type">mysql_xdevapi\CrudOperationSortable <span class="methodname">mysql_xdevapi\CrudOperationSortable::sort ( string $sort_expr )

Sort the result set by the field selected in the sort_expr argument. The allowed orders are ASC (Ascending) or DESC (Descending). This operation is equivalent to the 'ORDER BY' SQL operation and it follows the same set of rules.

Warning

本函数还未编写文档,仅有参数列表。

参数

sort_expr
One or more sorting expressions can be provided. The evaluation is from left to right, and each expression is separated by a comma.

返回值

A CrudOperationSortable object.

范例

示例 #1 <span class="function">mysql_xdevapi\CrudOperationSortable::sort example

<?php

$res = $coll->find('job like \'Cavia\'')->sort('age desc', '_id desc')->execute();

?>

简介

类摘要

mysql_xdevapi\DatabaseObject

class mysql_xdevapi\DatabaseObject {

/* 方法 */

abstract <span class="modifier">public bool <span class="methodname">existsInDatabase ( <span class="methodparam">void )

abstract <span class="modifier">public string <span class="methodname">getName ( <span class="methodparam">void )

abstract <span class="modifier">public <span class="type">mysql_xdevapi\Session <span class="methodname">getSession ( <span class="methodparam">void )

}

DatabaseObject::existsInDatabase

Check if object exists in database

说明

abstract <span class="modifier">public bool <span class="methodname">mysql_xdevapi\DatabaseObject::existsInDatabase ( void )

Verifies if the database object refers to an object that exists in the database.

参数

此函数没有参数。

返回值

Returns true if object exists in the database, else false if it does not.

范例

示例 #1 <span class="function">mysql_xdevapi\DatabaseObject::existsInDatabase example

<?php

$existInDb = $dbObj->existsInDatabase();

?>

DatabaseObject::getName

Get object name

说明

abstract <span class="modifier">public string <span class="methodname">mysql_xdevapi\DatabaseObject::getName ( void )

Fetch name of this database object.

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

The name of this database object.

范例

示例 #1 <span class="function">mysql_xdevapi\DatabaseObject::getName example

<?php

$dbObjName = $dbObj->getName();

?>

DatabaseObject::getSession

Get session name

说明

abstract <span class="modifier">public <span class="type">mysql_xdevapi\Session <span class="methodname">mysql_xdevapi\DatabaseObject::getSession ( void )

Fetch session associated to the database object.

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

The Session object.

范例

示例 #1 <span class="function">mysql_xdevapi\DatabaseObject::getSession example

<?php

$session = $dbObj->getSession();

?>

简介

类摘要

mysql_xdevapi\DocResult

class mysql_xdevapi\DocResult <span class="oointerface">implements <span class="interfacename">mysql_xdevapi\BaseResult <span class="oointerface">, Traversable {

/* 方法 */

public array fetchAll ( <span class="methodparam">void )

public array fetchOne ( <span class="methodparam">void )

public Array getWarnings ( <span class="methodparam">void )

public int <span class="methodname">getWarningsCount ( <span class="methodparam">void )

}

DocResult::__construct

DocResult constructor

说明

private <span class="methodname">mysql_xdevapi\DocResult::__construct ( void )

Fetch document results and warnings, and is instantiated by CollectionFind.

参数

此函数没有参数。

范例

示例 #1 A DocResult example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");

$create->add('{"name": "Alfred", "age": 18, "job": "Butler"}')->execute();
$create->add('{"name": "Reginald", "age": 42, "job": "Butler"}')->execute();

// ...

$collection = $schema->getCollection("people");

// Yields a DocResult object
$result = $collection
  ->find('job like :job and age > :age')
  ->bind(['job' => 'Butler', 'age' => 16])
  ->sort('age desc')
  ->limit(1)
  ->execute();

var_dump($result->fetchAll());
?>

以上例程的输出类似于:

array(1) {
  [0]=>
  array(4) {
    ["_id"]=>
    string(28) "00005b6b536100000000000000f3"
    ["age"]=>
    int(42)
    ["job"]=>
    string(6) "Butler"
    ["name"]=>
    string(8) "Reginald"
  }
}

DocResult::fetchAll

Get all rows

说明

public array mysql_xdevapi\DocResult::fetchAll ( void )

Fetch all results from a result set.

参数

此函数没有参数。

返回值

A numerical array with all results from the query; each result is an associative array. An empty array is returned if no rows are present.

范例

示例 #1 <span class="function">mysql_xdevapi\DocResult::fetchAll example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");

$create->add('{"name": "Alfred", "age": 18, "job": "Butler"}')->execute();
$create->add('{"name": "Reginald", "age": 42, "job": "Butler"}')->execute();

// ...

$collection = $schema->getCollection("people");

// Yields a DocResult object
$result = $collection
  ->find('job like :job and age > :age')
  ->bind(['job' => 'Butler', 'age' => 16])
  ->sort('age desc')
  ->execute();

var_dump($result->fetchAll());
?>

以上例程的输出类似于:

array(2) {

  [0]=>
  array(4) {
    ["_id"]=>
    string(28) "00005b6b53610000000000000123"
    ["age"]=>
    int(42)
    ["job"]=>
    string(6) "Butler"
    ["name"]=>
    string(8) "Reginald"
  }

  [1]=>
  array(4) {
    ["_id"]=>
    string(28) "00005b6b53610000000000000122"
    ["age"]=>
    int(18)
    ["job"]=>
    string(6) "Butler"
    ["name"]=>
    string(6) "Alfred"
  }

}

DocResult::fetchOne

Get one row

说明

public array mysql_xdevapi\DocResult::fetchOne ( void )

Fetch one result from a result set.

参数

此函数没有参数。

返回值

The result, as an associative array or null if no results are present.

范例

示例 #1 <span class="function">mysql_xdevapi\DocResult::fetchOne example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");

$create->add('{"name": "Alfred", "age": 18, "job": "Butler"}')->execute();
$create->add('{"name": "Reginald", "age": 42, "job": "Butler"}')->execute();

// ...

$collection = $schema->getCollection("people");

// Yields a DocResult object
$result = $collection
  ->find('job like :job and age > :age')
  ->bind(['job' => 'Butler', 'age' => 16])
  ->sort('age desc')
  ->execute();

var_dump($result->fetchOne());
?>

以上例程的输出类似于:

array(4) {
  ["_id"]=>
  string(28) "00005b6b53610000000000000125"
  ["age"]=>
  int(42)
  ["job"]=>
  string(6) "Butler"
  ["name"]=>
  string(8) "Reginald"
}

DocResult::getWarnings

Get warnings from last operation

说明

public Array mysql_xdevapi\DocResult::getWarnings ( void )

Fetches warnings generated by MySQL server's last operation.

参数

此函数没有参数。

返回值

An array of Warning objects from the last operation. Each object defines an error 'message', error 'level', and error 'code'. An empty array is returned if no errors are present.

范例

示例 #1 <span class="function">mysql_xdevapi\DocResult::getWarnings example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");

$create->add('{"name": "Alfred", "age": 18, "job": "Butler"}')->execute();
$create->add('{"name": "Reginald", "age": 42, "job": "Butler"}')->execute();

// ...

$collection = $schema->getCollection("people");

// Yields a DocResult object
$result = $collection
  ->find('job like :job and age > :age')
  ->bind(['job' => 'Butler', 'age' => 16])
  ->sort('age desc')
  ->execute();

if (!$result->getWarningsCount()) {
    echo "There was an error:\n";
    print_r($result->getWarnings());
    exit;
}

var_dump($result->fetchOne());
?>

以上例程的输出类似于:

There was an error:

Array
(
    [0] => mysql_xdevapi\Warning Object
        (
            [message] => Something bad and so on
            [level] => 2
            [code] => 1365
        )
    [1] => mysql_xdevapi\Warning Object
        (
            [message] => Something bad and so on
            [level] => 2
            [code] => 1365
        )
)

DocResult::getWarningsCount

Get warning count from last operation

说明

public int <span class="methodname">mysql_xdevapi\DocResult::getWarningsCount ( void )

Returns the number of warnings raised by the last operation. Specifically, these warnings are raised by the MySQL server.

参数

此函数没有参数。

返回值

The number of warnings from the last operation.

范例

示例 #1 <span class="function">mysql_xdevapi\DocResult::getWarningsCount example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");

$create->add('{"name": "Alfred", "age": 18, "job": "Butler"}')->execute();
$create->add('{"name": "Reginald", "age": 42, "job": "Butler"}')->execute();

// ...

$collection = $schema->getCollection("people");

// Yields a DocResult object
$result = $collection
  ->find('job like :job and age > :age')
  ->bind(['job' => 'Butler', 'age' => 16])
  ->sort('age desc')
  ->execute();

if (!$result->getWarningsCount()) {
    echo "There was an error:\n";
    print_r($result->getWarnings());
    exit;
}

var_dump($result->fetchOne());
?>

以上例程的输出类似于:

array(4) {
  ["_id"]=>
  string(28) "00005b6b53610000000000000135"
  ["age"]=>
  int(42)
  ["job"]=>
  string(6) "Butler"
  ["name"]=>
  string(8) "Reginald"
}

简介

类摘要

mysql_xdevapi\Exception

class mysql_xdevapi\Exception <span class="ooclass"> extends RuntimeException implements <span class="interfacename">Throwable {

}

简介

类摘要

mysql_xdevapi\Executable

class mysql_xdevapi\Executable {

/* 方法 */

abstract <span class="modifier">public <span class="type">mysql_xdevapi\Result <span class="methodname">execute ( <span class="methodparam">void )

}

Executable::execute

Execute statement

说明

abstract <span class="modifier">public <span class="type">mysql_xdevapi\Result <span class="methodname">mysql_xdevapi\Executable::execute ( <span class="methodparam">void )

Execute the statement from either a collection operation or a table query; this functionality allows for method chaining.

参数

此函数没有参数。

返回值

One of the Result objects, such as Result or SqlStatementResult.

范例

示例 #1 execute() examples

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$result_sql = $session->sql("CREATE DATABASE addressbook")->execute();

var_dump($result_sql);


$schema     = $session->getSchema("addressbook");
$collection = $schema->createCollection("humans");

$result_collection = $collection->add(
  '{"name": "Jane",
    "jobs": [{"title":"Scientist","Salary":18000}, {"title":"Mother","Salary":0}],
    "hobbies": ["Walking","Making pies"]}');

$result_collection_executed = $result_collection->execute();

var_dump($result_collection);
var_dump($result_collection_executed);
?>

以上例程的输出类似于:

object(mysql_xdevapi\SqlStatementResult)#3 (0) {
}

object(mysql_xdevapi\CollectionAdd)#5 (0) {
}

object(mysql_xdevapi\Result)#7 (0) {
}

简介

类摘要

mysql_xdevapi\ExecutionStatus

class mysql_xdevapi\ExecutionStatus {

/* 属性 */

public $affectedItems ;

public $matchedItems ;

public $foundItems ;

public $lastInsertId ;

public $lastDocumentId ;

/* Constructor */

private <span class="methodname">__construct ( <span class="methodparam">void )

}

属性

affectedItems

matchedItems

foundItems

lastInsertId

lastDocumentId

ExecutionStatus::__construct

ExecutionStatus constructor

说明

private <span class="methodname">mysql_xdevapi\ExecutionStatus::__construct ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

范例

示例 #1 <span class="function">mysql_xdevapi\ExecutionStatus::__construct example

<?php

/* ... */

?>

简介

类摘要

mysql_xdevapi\Expression

class mysql_xdevapi\Expression {

/* 属性 */

public $name ;

/* Constructor */

public <span class="methodname">__construct ( <span class="methodparam">string $expression )

}

属性

name

Expression::__construct

Expression constructor

说明

public <span class="methodname">mysql_xdevapi\Expression::__construct ( string $expression )

Warning

本函数还未编写文档,仅有参数列表。

参数

expression

范例

示例 #1 <span class="function">mysql_xdevapi\Expression::__construct example

<?php

/* ... */

?>

简介

类摘要

mysql_xdevapi\Result

class mysql_xdevapi\Result <span class="oointerface">implements <span class="interfacename">mysql_xdevapi\BaseResult <span class="oointerface">, Traversable {

/* 方法 */

public int <span class="methodname">getAffectedItemsCount ( <span class="methodparam">void )

public int <span class="methodname">getAutoIncrementValue ( <span class="methodparam">void )

public array getGeneratedIds ( <span class="methodparam">void )

public array getWarnings ( <span class="methodparam">void )

public int <span class="methodname">getWarningsCount ( <span class="methodparam">void )

}

Result::__construct

Result constructor

说明

private <span class="methodname">mysql_xdevapi\Result::__construct ( <span class="methodparam">void )

An object that retrieves generated IDs, AUTO_INCREMENT values, and warnings, for a Result set.

参数

此函数没有参数。

范例

示例 #1 <span class="function">mysql_xdevapi\Result::__construct example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("
  CREATE TABLE addressbook.names
    (id INT NOT NULL AUTO_INCREMENT, name VARCHAR(30), age INT, PRIMARY KEY (id))
  ")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$result = $table->insert("name", "age")->values(["Suzanne", 31],["Julie", 43])->execute();
$result = $table->insert("name", "age")->values(["Suki", 34])->execute();

$ai = $result->getAutoIncrementValue();
var_dump($ai);
?>

以上例程会输出:

int(3)

Result::getAffectedItemsCount

Get affected row count

说明

public int <span class="methodname">mysql_xdevapi\Result::getAffectedItemsCount ( void )

Get the number of affected rows by the previous operation.

参数

此函数没有参数。

返回值

The number (as an integer) of affected rows.

范例

示例 #1 <span class="function">mysql_xdevapi\Result::getAffectedItemsCount example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");

$collection = $schema->getCollection("people");

$result = $collection->add('{"name": "Wilma", "age": 23, "job": "Teacher"}')->execute();

var_dump( $res->getAffectedItemsCount() );
?>

以上例程会输出:

int(1)

Result::getAutoIncrementValue

Get autoincremented value

说明

public int <span class="methodname">mysql_xdevapi\Result::getAutoIncrementValue ( void )

Get the last AUTO_INCREMENT value (last insert id).

参数

此函数没有参数。

返回值

The last AUTO_INCREMENT value.

范例

示例 #1 <span class="function">mysql_xdevapi\Result::getAutoIncrementValue example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("
  CREATE TABLE addressbook.names
    (id INT NOT NULL AUTO_INCREMENT, name VARCHAR(30), age INT, PRIMARY KEY (id))
  ")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$result = $table->insert("name", "age")->values(["Suzanne", 31],["Julie", 43])->execute();
$result = $table->insert("name", "age")->values(["Suki", 34])->execute();

$ai = $result->getAutoIncrementValue();
var_dump($ai);
?>

以上例程会输出:

int(3)

Result::getGeneratedIds

Get generated ids

说明

public array mysql_xdevapi\Result::getGeneratedIds ( void )

Fetch the generated _id values from the last operation. The unique _id field is generated by the MySQL server.

参数

此函数没有参数。

返回值

An array of generated _id's from the last operation, or an empty array if there are none.

范例

示例 #1 <span class="function">mysql_xdevapi\Result::getGeneratedIds example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema = $session->getSchema("addressbook");
$create = $schema->createCollection("people");

$collection = $schema->getCollection("people");

$result = $collection->add(
  '{"name": "Bernie",
    "jobs": [{"title":"Cat Herder","Salary":42000}, {"title":"Father","Salary":0}],
    "hobbies": ["Sports","Making cupcakes"]}',
  '{"name": "Jane",
    "jobs": [{"title":"Scientist","Salary":18000}, {"title":"Mother","Salary":0}],
    "hobbies": ["Walking","Making pies"]}')->execute();

$ids = $result->getGeneratedIds();
var_dump($ids);
?>

以上例程的输出类似于:

array(2) {
  [0]=>
  string(28) "00005b6b53610000000000000064"
  [1]=>
  string(28) "00005b6b53610000000000000065"
}

Result::getWarnings

Get warnings from last operation

说明

public array mysql_xdevapi\Result::getWarnings ( void )

Retrieve warnings from the last Result operation.

参数

此函数没有参数。

返回值

An array of Warning objects from the last operation. Each object defines an error 'message', error 'level', and error 'code'. An empty array is returned if no errors are present.

范例

示例 #1 <span class="function">mysql_xdevapi\RowResult::getWarnings example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("CREATE DATABASE foo")->execute();
$session->sql("CREATE TABLE foo.test_table(x int)")->execute();

$schema = $session->getSchema("foo");
$table  = $schema->getTable("test_table");

$table->insert(['x'])->values([1])->values([2])->execute();

$res = $table->select(['x/0 as bad_x'])->execute();
$warnings = $res->getWarnings();

print_r($warnings);
?>

以上例程的输出类似于:

Array
(
    [0] => mysql_xdevapi\Warning Object
        (
            [message] => Division by 0
            [level] => 2
            [code] => 1365
        )
    [1] => mysql_xdevapi\Warning Object
        (
            [message] => Division by 0
            [level] => 2
            [code] => 1365
        )
)

Result::getWarningsCount

Get warning count from last operation

说明

public int <span class="methodname">mysql_xdevapi\Result::getWarningsCount ( void )

Retrieve the number of warnings from the last Result operation.

参数

此函数没有参数。

返回值

The number of warnings generated by the last operation.

范例

示例 #1 <span class="function">mysql_xdevapi\RowResult::getWarningsCount example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS foo")->execute();
$session->sql("CREATE DATABASE foo")->execute();
$session->sql("CREATE TABLE foo.test_table(x int)")->execute();

$schema = $session->getSchema("foo");
$table  = $schema->getTable("test_table");

$table->insert(['x'])->values([1])->values([2])->execute();

$res = $table->select(['x/0 as bad_x'])->execute();

echo $res->getWarningsCount();
?>

以上例程的输出类似于:

2

简介

类摘要

mysql_xdevapi\RowResult

class mysql_xdevapi\RowResult <span class="oointerface">implements <span class="interfacename">mysql_xdevapi\BaseResult <span class="oointerface">, Traversable {

/* 方法 */

public array fetchAll ( <span class="methodparam">void )

public array fetchOne ( <span class="methodparam">void )

public int <span class="methodname">getColumnsCount ( <span class="methodparam">void )

public array getColumnNames ( <span class="methodparam">void )

public array getColumns ( <span class="methodparam">void )

public array getWarnings ( <span class="methodparam">void )

public int <span class="methodname">getWarningsCount ( <span class="methodparam">void )

}

RowResult::__construct

RowResult constructor

说明

private <span class="methodname">mysql_xdevapi\RowResult::__construct ( void )

Represents the result set obtained from querying the database.

参数

此函数没有参数。

范例

示例 #1 <span class="function">mysql_xdevapi\RowResult::__construct example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$row = $table->select('name', 'age')->where('age > 18')->execute()->fetchAll();

print_r($row);

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [name] => John
            [age] => 42
        )
    [1] => Array
        (
            [name] => Sam
            [age] => 33
        )
)

RowResult::fetchAll

Get all rows from result

说明

public array mysql_xdevapi\RowResult::fetchAll ( void )

Fetch all the rows from the result set.

参数

此函数没有参数。

返回值

A numerical array with all results from the query; each result is an associative array. An empty array is returned if no rows are present.

范例

示例 #1 <span class="function">mysql_xdevapi\RowResult::fetchAll example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$row = $table->select('name', 'age')->execute()->fetchAll();

print_r($row);

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [name] => John
            [age] => 42
        )
    [1] => Array
        (
            [name] => Sam
            [age] => 33
        )
)

RowResult::fetchOne

Get row from result

说明

public array mysql_xdevapi\RowResult::fetchOne ( void )

Fetch one result from the result set.

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

The result, as an associative array or null if no results are present.

范例

示例 #1 <span class="function">mysql_xdevapi\RowResult::fetchOne example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$row = $table->select('name', 'age')->where('age < 40')->execute()->fetchOne();

print_r($row);

以上例程的输出类似于:

Array
(
    [name] => Sam
    [age] => 33
)

RowResult::getColumnsCount

Get column count

说明

public int <span class="methodname">mysql_xdevapi\RowResult::getColumnsCount ( void )

Retrieve the column count for columns present in the result set.

参数

此函数没有参数。

返回值

The number of columns; 0 if there are none.

更新日志

版本 说明
8.0.14 Method renamed from getColumnCount() to getColumnsCount().

范例

示例 #1 <span class="function">mysql_xdevapi\RowResult::getColumnsCount example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE addressbook")->execute();
$session->sql("CREATE DATABASE foo")->execute();
$session->sql("CREATE TABLE foo.test_table(x int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$sql = $session->sql("SELECT * from addressbook.names")->execute();

echo $sql->getColumnsCount();

以上例程的输出类似于:

2

RowResult::getColumnNames

Get all column names

说明

public array <span class="methodname">mysql_xdevapi\RowResult::getColumnNames ( void )

Retrieve column names for columns present in the result set.

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

A numerical array of table columns names, or an empty array if the result set is empty.

范例

示例 #1 <span class="function">mysql_xdevapi\RowResult::getColumnNames example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE addressbook")->execute();
$session->sql("CREATE DATABASE foo")->execute();
$session->sql("CREATE TABLE foo.test_table(x int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$sql = $session->sql("SELECT * from addressbook.names")->execute();

$colnames = $sql->getColumnNames();

print_r($colnames);

以上例程的输出类似于:

Array
(
    [0] => name
    [1] => age
)

RowResult::getColumns

Get column metadata

说明

public array mysql_xdevapi\RowResult::getColumns ( void )

Retrieve column metadata for columns present in the result set.

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

An array of FieldMetadata objects representing the columns in the result, or an empty array if the result set is empty.

范例

示例 #1 <span class="function">mysql_xdevapi\RowResult::getColumns example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE addressbook")->execute();
$session->sql("CREATE DATABASE foo")->execute();
$session->sql("CREATE TABLE foo.test_table(x int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$sql = $session->sql("SELECT * from addressbook.names")->execute();

$cols = $sql->getColumns();

print_r($cols);

以上例程的输出类似于:

Array
(
    [0] => mysql_xdevapi\FieldMetadata Object
        (
            [type] => 7
            [type_name] => BYTES
            [name] => name
            [original_name] => name
            [table] => names
            [original_table] => names
            [schema] => addressbook
            [catalog] => def
            [collation] => 255
            [fractional_digits] => 0
            [length] => 65535
            [flags] => 0
            [content_type] => 0
        )
    [1] => mysql_xdevapi\FieldMetadata Object
        (
            [type] => 1
            [type_name] => SINT
            [name] => age
            [original_name] => age
            [table] => names
            [original_table] => names
            [schema] => addressbook
            [catalog] => def
            [collation] => 0
            [fractional_digits] => 0
            [length] => 11
            [flags] => 0
            [content_type] => 0
        )
)

RowResult::getWarnings

Get warnings from last operation

说明

public array mysql_xdevapi\RowResult::getWarnings ( void )

Retrieve warnings from the last RowResult operation.

参数

此函数没有参数。

返回值

An array of Warning objects from the last operation. Each object defines an error 'message', error 'level', and error 'code'. An empty array is returned if no errors are present.

范例

示例 #1 <span class="function">mysql_xdevapi\RowResult::getWarnings example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("CREATE DATABASE foo")->execute();
$session->sql("CREATE TABLE foo.test_table(x int)")->execute();

$schema = $session->getSchema("foo");
$table  = $schema->getTable("test_table");

$table->insert(['x'])->values([1])->values([2])->execute();

$res = $table->select(['x/0 as bad_x'])->execute();
$warnings = $res->getWarnings();

print_r($warnings);
?>

以上例程的输出类似于:

Array
(
    [0] => mysql_xdevapi\Warning Object
        (
            [message] => Division by 0
            [level] => 2
            [code] => 1365
        )
    [1] => mysql_xdevapi\Warning Object
        (
            [message] => Division by 0
            [level] => 2
            [code] => 1365
        )
)

RowResult::getWarningsCount

Get warning count from last operation

说明

public int <span class="methodname">mysql_xdevapi\RowResult::getWarningsCount ( void )

Retrieve the number of warnings from the last RowResult operation.

参数

此函数没有参数。

返回值

The number of warnings generated by the last operation.

范例

示例 #1 <span class="function">mysql_xdevapi\RowResult::getWarningsCount example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS foo")->execute();
$session->sql("CREATE DATABASE foo")->execute();
$session->sql("CREATE TABLE foo.test_table(x int)")->execute();

$schema = $session->getSchema("foo");
$table  = $schema->getTable("test_table");

$table->insert(['x'])->values([1])->values([2])->execute();

$res = $table->select(['x/0 as bad_x'])->execute();

echo $res->getWarningsCount();
?>

以上例程的输出类似于:

2

简介

类摘要

mysql_xdevapi\Schema

class mysql_xdevapi\Schema <span class="oointerface">implements <span class="interfacename">mysql_xdevapi\DatabaseObject {

/* 属性 */

public $name ;

/* 方法 */

public <span class="type">mysql_xdevapi\Collection <span class="methodname">createCollection ( <span class="methodparam">string $name )

public bool dropCollection ( <span class="methodparam">string $collection_name )

public bool existsInDatabase ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\Collection <span class="methodname">getCollection ( <span class="methodparam">string $name )

public <span class="type">mysql_xdevapi\Table <span class="methodname">getCollectionAsTable ( <span class="methodparam">string $name )

public array getCollections ( <span class="methodparam">void )

public string getName ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\Session <span class="methodname">getSession ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\Table <span class="methodname">getTable ( <span class="type">string $name )

public array getTables ( <span class="methodparam">void )

}

属性

name

Schema::__construct

constructor

说明

private <span class="methodname">mysql_xdevapi\Schema::__construct ( <span class="methodparam">void )

The Schema object provides full access to the schema (database).

参数

此函数没有参数。

范例

示例 #1 Schema::__construct example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS food")->execute();
$session->sql("CREATE DATABASE food")->execute();
$session->sql("CREATE TABLE food.fruit(name text, rating text)")->execute();

$schema = $session->getSchema("food");
$schema->createCollection("trees");

print_r($schema->gettables());
print_r($schema->getcollections());

以上例程的输出类似于:

Array
(
    [fruit] => mysql_xdevapi\Table Object
        (
            [name] => fruit
        )
)
Array
(
    [trees] => mysql_xdevapi\Collection Object
        (
            [name] => trees
        )
)

Schema::createCollection

Add collection to schema

说明

public <span class="type">mysql_xdevapi\Collection <span class="methodname">mysql_xdevapi\Schema::createCollection ( string $name )

Create a collection within the schema.

Warning

本函数还未编写文档,仅有参数列表。

参数

name

返回值

范例

示例 #1 Schema::createCollection example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS food")->execute();
$session->sql("CREATE DATABASE food")->execute();
$session->sql("CREATE TABLE food.fruit(name text, rating text)")->execute();

$schema = $session->getSchema("food");
$schema->createCollection("trees");

print_r($schema->gettables());
print_r($schema->getcollections());

以上例程的输出类似于:

Array
(
    [fruit] => mysql_xdevapi\Table Object
        (
            [name] => fruit
        )
)
Array
(
    [trees] => mysql_xdevapi\Collection Object
        (
            [name] => trees
        )
)

Schema::dropCollection

Drop collection from schema

说明

public bool mysql_xdevapi\Schema::dropCollection ( string $collection_name )

Warning

本函数还未编写文档,仅有参数列表。

参数

collection_name

返回值

范例

示例 #1 Schema::dropCollection example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS food")->execute();
$session->sql("CREATE DATABASE food")->execute();
$session->sql("CREATE TABLE food.fruit(name text, rating text)")->execute();

$schema = $session->getSchema("food");

$schema->createCollection("trees");
$schema->dropCollection("trees");
$schema->createCollection("buildings");

print_r($schema->gettables());
print_r($schema->getcollections());

以上例程的输出类似于:

Array
(
    [fruit] => mysql_xdevapi\Table Object
        (
            [name] => fruit
        )
)
Array
(
    [buildings] => mysql_xdevapi\Collection Object
        (
            [name] => buildings
        )
)

Schema::existsInDatabase

Check if exists in database

说明

public bool mysql_xdevapi\Schema::existsInDatabase ( void )

Checks if the current object (schema, table, collection, or view) exists in the schema object.

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

true if the schema, table, collection, or view still exists in the schema, else false.

范例

示例 #1 Schema::existsInDatabase example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS food")->execute();
$session->sql("CREATE DATABASE food")->execute();
$session->sql("CREATE TABLE food.fruit(name text, rating text)")->execute();

$schema = $session->getSchema("food");
$schema->createCollection("trees");

// ...

$trees = $schema->getCollection("trees");

// ...

// Is this collection still in the database (schema)?
if ($trees->existsInDatabase()) {
    echo "Yes, the 'trees' collection is still present.";
}

以上例程的输出类似于:

Yes, the 'trees' collection is still present.

Schema::getCollection

Get collection from schema

说明

public <span class="type">mysql_xdevapi\Collection <span class="methodname">mysql_xdevapi\Schema::getCollection ( <span class="methodparam">string $name )

Get a collection from the schema.

参数

name
Collection name to retrieve.

返回值

The Collection object for the selected collection.

范例

示例 #1 Schema::getCollection example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS food")->execute();
$session->sql("CREATE DATABASE food")->execute();

$schema = $session->getSchema("food");
$schema->createCollection("trees");

// ...

$trees = $schema->getCollection("trees");

var_dump($trees);

以上例程的输出类似于:

object(mysql_xdevapi\Collection)#3 (1) {
  ["name"]=>
  string(5) "trees"
}

Schema::getCollectionAsTable

Get collection table object

说明

public <span class="type">mysql_xdevapi\Table <span class="methodname">mysql_xdevapi\Schema::getCollectionAsTable ( string $name )

Get a collection, but as a Table object instead of a Collection object.

参数

name
Name of the collection to instantiate a Table object from.

返回值

A table object for the collection.

范例

示例 #1 Schema::getCollectionAsTable example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema  = $session->getSchema("addressbook");
$collect = $schema->createCollection("people");
$collect->add('{"name": "Fred",  "age": 21, "job": "Construction"}')->execute();
$collect->add('{"name": "Wilma", "age": 23, "job": "Teacher"}')->execute();

$table      = $schema->getCollectionAsTable("people");
$collection = $schema->getCollection("people");

var_dump($table);
var_dump($collection);

以上例程的输出类似于:

object(mysql_xdevapi\Table)#4 (1) {
  ["name"]=>
  string(6) "people"
}

object(mysql_xdevapi\Collection)#5 (1) {
  ["name"]=>
  string(6) "people"
}

Schema::getCollections

Get all schema collections

说明

public array mysql_xdevapi\Schema::getCollections ( void )

Fetch a list of collections for this schema.

参数

此函数没有参数。

返回值

Array of all collections in this schema, where each array element value is a Collection object with the collection name as the key.

范例

示例 #1 <span class="function">mysql_xdevapi\Schema::getCollections example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema  = $session->getSchema("addressbook");
$collect = $schema->createCollection("people");
$collect->add('{"name": "Fred",  "age": 21, "job": "Construction"}')->execute();
$collect->add('{"name": "Wilma", "age": 23, "job": "Teacher"}')->execute();

$collections = $schema->getCollections();
var_dump($collections);
?>

以上例程的输出类似于:

array(1) {
  ["people"]=>
  object(mysql_xdevapi\Collection)#4 (1) {
    ["name"]=>
    string(6) "people"
  }
}

Schema::getName

Get schema name

说明

public string mysql_xdevapi\Schema::getName ( <span class="methodparam">void )

Get the name of the schema.

参数

此函数没有参数。

返回值

The name of the schema connected to the schema object, as a string.

范例

示例 #1 mysql_xdevapi\Schema::getName example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema  = $session->getSchema("addressbook");

// ...

var_dump($schema->getName());
?>

以上例程的输出类似于:

string(11) "addressbook"

Schema::getSession

Get schema session

说明

public <span class="type">mysql_xdevapi\Session <span class="methodname">mysql_xdevapi\Schema::getSession ( <span class="methodparam">void )

Get a new Session object from the Schema object.

参数

此函数没有参数。

返回值

A Session object.

范例

示例 #1 <span class="function">mysql_xdevapi\Schema::getSession example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$schema  = $session->getSchema("addressbook");

// ...

$newsession = $schema->getSession();

var_dump($session);
var_dump($newsession);
?>

以上例程的输出类似于:

object(mysql_xdevapi\Session)#1 (0) {
}

object(mysql_xdevapi\Session)#3 (0) {
}

Schema::getTable

Get schema table

说明

public <span class="type">mysql_xdevapi\Table <span class="methodname">mysql_xdevapi\Schema::getTable ( <span class="methodparam">string $name )

Fetch a Table object for the provided table in the schema.

参数

name
Name of the table.

返回值

A Table object.

范例

示例 #1 <span class="function">mysql_xdevapi\Schema::getTable example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$row = $table->select('name', 'age')->execute()->fetchAll();

print_r($row);
?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [name] => John
            [age] => 42
        )
    [1] => Array
        (
            [name] => Sam
            [age] => 33
        )
)

Schema::getTables

Get schema tables

说明

public array mysql_xdevapi\Schema::getTables ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

Array of all tables in this schema, where each array element value is a Table object with the table name as the key.

范例

示例 #1 <span class="function">mysql_xdevapi\Schema::getTables example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();

$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$session->sql("CREATE TABLE addressbook.cities(name text, population int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('Portland', 639863), ('Seattle', 704352)")->execute();

$schema = $session->getSchema("addressbook");
$tables = $schema->getTables();

var_dump($tables);
?>

以上例程的输出类似于:

array(2) {
  ["cities"]=>
  object(mysql_xdevapi\Table)#3 (1) {
    ["name"]=>
    string(6) "cities"
  }

  ["names"]=>
  object(mysql_xdevapi\Table)#4 (1) {
    ["name"]=>
    string(5) "names"
  }
}

简介

类摘要

mysql_xdevapi\SchemaObject

class mysql_xdevapi\SchemaObject implements <span class="interfacename">mysql_xdevapi\DatabaseObject {

/* 方法 */

abstract <span class="type">mysql_xdevapi\Schema <span class="methodname">getSchema ( <span class="methodparam">void )

}

SchemaObject::getSchema

Get schema object

说明

abstract <span class="type">mysql_xdevapi\Schema <span class="methodname">mysql_xdevapi\SchemaObject::getSchema ( void )

Used by other objects to retrieve a schema object.

参数

此函数没有参数。

返回值

The current Schema object.

范例

示例 #1 <span class="function">mysql_xdevapi\Session::getSchema example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$schema  = $session->getSchema("addressbook");

print_r($schema);

以上例程的输出类似于:

mysql_xdevapi\Schema Object
(
    [name] => addressbook
)

简介

类摘要

mysql_xdevapi\Session

class mysql_xdevapi\Session {

/* 方法 */

public bool close ( <span class="methodparam">void )

public Object commit ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\Schema <span class="methodname">createSchema ( <span class="type">string $schema_name )

public bool dropSchema ( <span class="methodparam">string $schema_name )

public string generateUUID ( <span class="methodparam">void )

public string getDefaultSchema ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\Schema <span class="methodname">getSchema ( <span class="type">string $schema_name )

public array getSchemas ( <span class="methodparam">void )

public int <span class="methodname">getServerVersion ( <span class="methodparam">void )

public array listClients ( <span class="methodparam">void )

public string quoteName ( <span class="methodparam">string $name )

public void releaseSavepoint ( <span class="methodparam">string $name )

public void rollback ( <span class="methodparam">void )

public void rollbackTo ( <span class="methodparam">string $name )

public string setSavepoint ([ <span class="methodparam">string $name ] )

public <span class="type">mysql_xdevapi\SqlStatement <span class="methodname">sql ( <span class="type">string $query )

public void startTransaction ( <span class="methodparam">void )

}

Session::close

Close session

说明

public bool mysql_xdevapi\Session::close ( <span class="methodparam">void )

Close the session with the server.

参数

此函数没有参数。

返回值

true if the session closed.

范例

示例 #1 mysql_xdevapi\Session::close example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$session->close();

Session::commit

Commit transaction

说明

public Object mysql_xdevapi\Session::commit ( <span class="methodparam">void )

Commit the transaction.

参数

此函数没有参数。

返回值

An SqlStatementResult object.

范例

示例 #1 mysql_xdevapi\Session::commit example

<?php
$session    = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$collection = $session->getSchema("addressbook")->getCollection("friends");

$session->startTransaction();

$collection->add('{"John":42, "Sam":33}')->execute();
$savepoint = $session->setSavepoint();

$session->commit();
$session->close();

Session::__construct

Description constructor

说明

private <span class="methodname">mysql_xdevapi\Session::__construct ( <span class="methodparam">void )

A Session object, as initiated by getSession().

参数

此函数没有参数。

范例

示例 #1 <span class="function">mysql_xdevapi\Session::__construct example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->close();
?>

Session::createSchema

Create new schema

说明

public <span class="type">mysql_xdevapi\Schema <span class="methodname">mysql_xdevapi\Session::createSchema ( <span class="methodparam">string $schema_name )

Creates a new schema.

参数

schema_name
Name of the schema to create.

返回值

A Schema object on success, and emits an exception on failure.

范例

示例 #1 <span class="function">mysql_xdevapi\Session::createSchema example

<?php
$uri  = 'mysqlx://happyuser:[email protected]:33060/';
$sess = mysql_xdevapi\getSession($uri);

try {

    if ($schema = $sess->createSchema('fruit')) {
        echo "Info: I created a schema named 'fruit'\n";
    }

} catch (Exception $e) {

   echo $e->getMessage();

}
?>

以上例程的输出类似于:

Info: I created a schema named 'fruit'

Session::dropSchema

Drop a schema

说明

public bool mysql_xdevapi\Session::dropSchema ( string $schema_name )

Drop a schema (database).

参数

schema_name
Name of the schema to drop.

返回值

true if the schema is dropped, or false if it does not exist or can't be dropped.

An E_WARNING level error is generated if the schema does not exist.

范例

示例 #1 <span class="function">mysql_xdevapi\Session::dropSchema example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->dropSchema("addressbook");

$session->close();
?>

Session::generateUUID

Get new UUID

说明

public string mysql_xdevapi\Session::generateUUID ( void )

Generate a Universal Unique IDentifier (UUID) generated according to » RFC 4122.

参数

此函数没有参数。

返回值

The UUID; a string with a length of 32.

范例

示例 #1 <span class="function">mysql_xdevapi\Session::generateUuid example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$uuid = $session->generateUuid();

var_dump($uuid);

以上例程的输出类似于:

string(32) "484B18AC7980F8D4FE84613CDA5EE84B"

Session::getDefaultSchema

Get default schema name

说明

public string <span class="methodname">mysql_xdevapi\Session::getDefaultSchema ( void )

Retrieve name of the default schema that's typically set in the connection URI.

参数

此函数没有参数。

返回值

Name of the default schema defined by the connection, or null if one was not set.

范例

示例 #1 <span class="function">mysql_xdevapi\Session::getSchema example

<?php
$uri = "mysqlx://testuser:testpasswd@localhost:33160/testx?ssl-mode=disabled";
$session = mysql_xdevapi\getSession($uri);

$schema = $session->getDefaultSchema();
echo $schema;
?>

以上例程会输出:

testx

Session::getSchema

Get a new schema object

说明

public <span class="type">mysql_xdevapi\Schema <span class="methodname">mysql_xdevapi\Session::getSchema ( <span class="methodparam">string $schema_name )

A new Schema object for the provided schema name.

参数

schema_name
Name of the schema (database) to fetch a Schema object for.

返回值

A Schema object.

范例

示例 #1 <span class="function">mysql_xdevapi\Session::getSchema example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$schema  = $session->getSchema("addressbook");

print_r($schema);

以上例程的输出类似于:

mysql_xdevapi\Schema Object
(
    [name] => addressbook
)

Session::getSchemas

Get the schemas

说明

public array mysql_xdevapi\Session::getSchemas ( void )

Get schema objects for all schemas available to the session.

参数

此函数没有参数。

返回值

An array containing objects that represent all of the schemas available to the session.

范例

示例 #1 <span class="function">mysql_xdevapi\Session::getSchemas example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$schemas  = $session->getSchemas();

print_r($schemas);

以上例程的输出类似于:

Array
(
    [0] => mysql_xdevapi\Schema Object
        (
            [name] => addressbook
        )
    [1] => mysql_xdevapi\Schema Object
        (
            [name] => information_schema
        )
    ...

Session::getServerVersion

Get server version

说明

public int <span class="methodname">mysql_xdevapi\Session::getServerVersion ( void )

Retrieve the MySQL server version for the session.

参数

此函数没有参数。

返回值

The MySQL server version for the session, as an integer such as "80012".

范例

示例 #1 <span class="function">mysql_xdevapi\Session::getServerVersion example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$version = $session->getServerVersion();

var_dump($version);

以上例程的输出类似于:

int(80012)

Session::listClients

Get client list

说明

public array mysql_xdevapi\Session::listClients ( void )

Get a list of client connections to the session's MySQL server.

参数

此函数没有参数。

返回值

An array containing the currently logged clients. The array elements are "client_id", "user", "host", and "sql_session".

范例

示例 #1 <span class="function">mysql_xdevapi\Session::listClients example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$ids = $session->listClients();

var_dump($ids);
?>

以上例程的输出类似于:

array(1) {
  [0]=>
  array(4) {
    ["client_id"]=>
    int(61)
    ["user"]=>
    string(4) "root"
    ["host"]=>
    string(9) "localhost"
    ["sql_session"]=>
    int(72)
  }
}

Session::quoteName

Add quotes

说明

public string mysql_xdevapi\Session::quoteName ( string $name )

A quoting function to escape SQL names and identifiers. It escapes the identifier given in accordance to the settings of the current connection. This escape function should not be used to escape values.

参数

name
The string to quote.

返回值

The quoted string.

范例

示例 #1 <span class="function">mysql_xdevapi\Session::quoteName example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$first = "MySQL's test";
var_dump($first);
var_dump($session->quoteName($first));

$second = 'Another `test` "like" `this`';
var_dump($second);
var_dump($session->quoteName($second));
?>

以上例程的输出类似于:

string(12) "MySQL's test"
string(14) "`MySQL's test`"

string(28) "Another `test` "like" `this`"
string(34) "`Another ``test`` "like" ``this```"

Session::releaseSavepoint

Release set savepoint

说明

public void <span class="methodname">mysql_xdevapi\Session::releaseSavepoint ( string $name )

Release a previously set savepoint.

参数

name
Name of the savepoint to release.

返回值

An SqlStatementResult object.

范例

示例 #1 <span class="function">mysql_xdevapi\Session::releaseSavepoint example

<?php
$session    = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$collection = $session->getSchema("addressbook")->getCollection("friends");

$session->startTransaction();
$collection->add( '{"test1":1, "test2":2}' )->execute();

$savepoint = $session->setSavepoint();

$collection->add( '{"test3":3, "test4":4}' )->execute();

$session->releaseSavepoint($savepoint);
$session->rollback();
?>

Session::rollback

Rollback transaction

说明

public void mysql_xdevapi\Session::rollback ( void )

Rollback the transaction.

参数

此函数没有参数。

返回值

An SqlStatementResult object.

范例

示例 #1 <span class="function">mysql_xdevapi\Session::rollback example

<?php
$session    = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$collection = $session->getSchema("addressbook")->getCollection("names");

$session->startTransaction();
$collection->add( '{"test1":1, "test2":2}' )->execute();

$savepoint = $session->setSavepoint();

$collection->add( '{"test3":3, "test4":4}' )->execute();

$session->releaseSavepoint($savepoint);
$session->rollback();
?>

Session::rollbackTo

Rollback transaction to savepoint

说明

public void mysql_xdevapi\Session::rollbackTo ( string $name )

Rollback the transaction back to the savepoint.

参数

name
Name of the savepoint to rollback to; case-insensitive.

返回值

An SqlStatementResult object.

范例

示例 #1 <span class="function">mysql_xdevapi\Session::rollbackTo example

<?php
$session    = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$collection = $session->getSchema("addressbook")->getCollection("names");

$session->startTransaction();
$collection->add( '{"test1":1, "test2":2}' )->execute();

$savepoint1 = $session->setSavepoint();

$collection->add( '{"test3":3, "test4":4}' )->execute();

$savepoint2 = $session->setSavepoint();

$session->rollbackTo($savepoint1);
?>

Session::setSavepoint

Create savepoint

说明

public string mysql_xdevapi\Session::setSavepoint ([ string $name ] )

Create a new savepoint for the transaction.

Warning

本函数还未编写文档,仅有参数列表。

参数

name
The name of the savepoint. The name is auto-generated if the optional name parameter is not defined as 'SAVEPOINT1', 'SAVEPOINT2', and so on.

返回值

The name of the save point.

范例

示例 #1 <span class="function">mysql_xdevapi\Session::setSavepoint example

<?php
$session    = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$collection = $session->getSchema("addressbook")->getCollection("names");

$session->startTransaction();
$collection->add( '{"test1":1, "test2":2}' )->execute();

$savepoint = $session->setSavepoint();

$collection->add( '{"test3":3, "test4":4}' )->execute();

$session->releaseSavepoint($savepoint);
$session->rollback();
?>

Session::sql

Execute SQL query

说明

public <span class="type">mysql_xdevapi\SqlStatement <span class="methodname">mysql_xdevapi\Session::sql ( <span class="methodparam">string $query )

Create a native SQL statement. Placeholders are supported using the native "?" syntax. Use the execute method to execute the SQL statement.

参数

query
SQL statement to execute.

返回值

An SqlStatement object.

范例

示例 #1 mysql_xdevapi\Session::sql example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("CREATE DATABASE addressbook")->execute();
?>

Session::startTransaction

Start transaction

说明

public void <span class="methodname">mysql_xdevapi\Session::startTransaction ( void )

Start a new transaction.

参数

此函数没有参数。

返回值

An SqlStatementResult object.

范例

示例 #1 <span class="function">mysql_xdevapi\Session::startTransaction example

<?php
$session    = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$collection = $session->getSchema("addressbook")->getCollection("friends");

$session->startTransaction();
$collection->add( '{"test1":1, "test2":2}' )->execute();

$savepoint = $session->setSavepoint();

$collection->add( '{"test3":3, "test4":4}' )->execute();

$session->releaseSavepoint($savepoint);
$session->rollback();
?>

简介

类摘要

mysql_xdevapi\SqlStatement

class mysql_xdevapi\SqlStatement {

/* Constants */

const int mysql_xdevapi\SqlStatement::EXECUTE_ASYNC = 1 ;

const int mysql_xdevapi\SqlStatement::BUFFERED = 2 ;

/* 属性 */

public $statement ;

/* 方法 */

public <span class="type">mysql_xdevapi\SqlStatement <span class="methodname">bind ( <span class="type">string $param )

public <span class="type">mysql_xdevapi\Result <span class="methodname">execute ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\Result <span class="methodname">getNextResult ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\Result <span class="methodname">getResult ( <span class="methodparam">void )

public bool hasMoreResults ( <span class="methodparam">void )

}

属性

statement

预定义常量

mysql_xdevapi\SqlStatement::EXECUTE_ASYNC

mysql_xdevapi\SqlStatement::BUFFERED

SqlStatement::bind

Bind statement parameters

说明

public <span class="type">mysql_xdevapi\SqlStatement <span class="methodname">mysql_xdevapi\SqlStatement::bind ( <span class="methodparam">string $param )

Warning

本函数还未编写文档,仅有参数列表。

参数

param

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\SqlStatement::bind example

<?php

/* ... */

?>

SqlStatement::__construct

Description constructor

说明

private <span class="methodname">mysql_xdevapi\SqlStatement::__construct ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

范例

示例 #1 <span class="function">mysql_xdevapi\SqlStatement::__construct example

<?php

/* ... */

?>

SqlStatement::execute

Execute the operation

说明

public <span class="type">mysql_xdevapi\Result <span class="methodname">mysql_xdevapi\SqlStatement::execute ( <span class="methodparam">void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\SqlStatement::execute example

<?php

/* ... */

?>

SqlStatement::getNextResult

Get next result

说明

public <span class="type">mysql_xdevapi\Result <span class="methodname">mysql_xdevapi\SqlStatement::getNextResult ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\SqlStatement::getNextResult example

<?php

/* ... */

?>

SqlStatement::getResult

Get result

说明

public <span class="type">mysql_xdevapi\Result <span class="methodname">mysql_xdevapi\SqlStatement::getResult ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\SqlStatement::getResult example

<?php

/* ... */

?>

SqlStatement::hasMoreResults

Check for more results

说明

public bool <span class="methodname">mysql_xdevapi\SqlStatement::hasMoreResults ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

true if the result set has more objects to fetch.

范例

示例 #1 <span class="function">mysql_xdevapi\SqlStatement::hasMoreResults example

<?php

/* ... */

?>

简介

类摘要

mysql_xdevapi\SqlStatementResult

class mysql_xdevapi\SqlStatementResult implements <span class="interfacename">mysql_xdevapi\BaseResult <span class="oointerface">, Traversable {

/* 方法 */

public array fetchAll ( <span class="methodparam">void )

public array fetchOne ( <span class="methodparam">void )

public int <span class="methodname">getAffectedItemsCount ( <span class="methodparam">void )

public int <span class="methodname">getColumnsCount ( <span class="methodparam">void )

public array getColumnNames ( <span class="methodparam">void )

public Array getColumns ( <span class="methodparam">void )

public array getGeneratedIds ( <span class="methodparam">void )

public String getLastInsertId ( <span class="methodparam">void )

public array getWarnings ( <span class="methodparam">void )

public int <span class="methodname">getWarningCounts ( <span class="methodparam">void )

public bool hasData ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\Result <span class="methodname">nextResult ( <span class="methodparam">void )

}

SqlStatementResult::__construct

Description constructor

说明

private <span class="methodname">mysql_xdevapi\SqlStatementResult::__construct ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

范例

示例 #1 <span class="function">mysql_xdevapi\SqlStatementResult::__construct example

<?php

/* ... */

?>

SqlStatementResult::fetchAll

Get all rows from result

说明

public array <span class="methodname">mysql_xdevapi\SqlStatementResult::fetchAll ( void )

Fetch all the rows from the result set.

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

A numerical array with all results from the query; each result is an associative array. An empty array is returned if no rows are present.

范例

示例 #1 <span class="function">mysql_xdevapi\SqlStatementResult::fetchAll example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS dbtest")->execute();
$session->sql("CREATE DATABASE dbtest")->execute();
$session->sql("CREATE TABLE dbtest.workers(name text, age int, job text)")->execute();
$session->sql("INSERT INTO dbtest.workers values ('John', 42, 'bricklayer'), ('Sam', 33, 'carpenter')")->execute();

$schema = $session->getSchema("dbtest");
$table  = $schema->getTable("workers");

$rows = $session->sql("SELECT * FROM dbtest.workers")->execute()->fetchAll();

print_r($rows);
?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [name] => John
            [age] => 42
        )
    [1] => Array
        (
            [name] => Sam
            [age] => 33
        )
)

SqlStatementResult::fetchOne

Get single row

说明

public array <span class="methodname">mysql_xdevapi\SqlStatementResult::fetchOne ( void )

Fetch one row from the result set.

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

The result, as an associative array. In case there is not any result, null will be returned.

范例

示例 #1 <span class="function">mysql_xdevapi\SqlStatementResult::fetchOne example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");
$session->sql("DROP DATABASE IF EXISTS dbtest")->execute();
$session->sql("CREATE DATABASE dbtest")->execute();
$session->sql("CREATE TABLE dbtest.workers(name text, age int, job text)")->execute();
$session->sql("INSERT INTO dbtest.workers values ('John', 42, 'bricklayer'), ('Sam', 33, 'carpenter')")->execute();

$schema = $session->getSchema("dbtest");
$table  = $schema->getTable("workers");

$rows = $session->sql("SELECT * FROM dbtest.workers")->execute()->fetchOne();

print_r($rows);
?>

以上例程的输出类似于:

Array
(
    [name] => John
    [age] => 42
    [job] => bricklayer
)

SqlStatementResult::getAffectedItemsCount

Get affected row count

说明

public int <span class="methodname">mysql_xdevapi\SqlStatementResult::getAffectedItemsCount ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\SqlStatementResult::getAffectedItemsCount example

<?php

/* ... */

?>

SqlStatementResult::getColumnsCount

Get column count

说明

public int <span class="methodname">mysql_xdevapi\SqlStatementResult::getColumnsCount ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

The number of columns; 0 if there are none.

更新日志

版本 说明
8.0.14 Method renamed from getColumnCount() to getColumnsCount().

范例

示例 #1 <span class="function">mysql_xdevapi\SqlStatementResult::getColumnsCount example

<?php

/* ... */

?>

SqlStatementResult::getColumnNames

Get column names

说明

public array <span class="methodname">mysql_xdevapi\SqlStatementResult::getColumnNames ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\SqlStatementResult::getColumnNames example

<?php

/* ... */

?>

SqlStatementResult::getColumns

Get columns

说明

public Array <span class="methodname">mysql_xdevapi\SqlStatementResult::getColumns ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\SqlStatementResult::getColumns example

<?php

/* ... */

?>

SqlStatementResult::getGeneratedIds

Get generated ids

说明

public array <span class="methodname">mysql_xdevapi\SqlStatementResult::getGeneratedIds ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

An array of generated _id's from the last operation, or an empty array if there are none.

范例

示例 #1 <span class="function">mysql_xdevapi\SqlStatementResult::getGeneratedIds example

<?php

/* ... */

?>

SqlStatementResult::getLastInsertId

Get last insert id

说明

public String <span class="methodname">mysql_xdevapi\SqlStatementResult::getLastInsertId ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

The ID for the last insert operation.

范例

示例 #1 <span class="function">mysql_xdevapi\SqlStatementResult::getLastInsertId example

<?php

/* ... */

?>

SqlStatementResult::getWarnings

Get warnings from last operation

说明

public array <span class="methodname">mysql_xdevapi\SqlStatementResult::getWarnings ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

An array of Warning objects from the last operation. Each object defines an error 'message', error 'level', and error 'code'. An empty array is returned if no errors are present.

范例

示例 #1 <span class="function">mysql_xdevapi\SqlStatementResult::getWarnings example

<?php

/* ... */

?>

SqlStatementResult::getWarningsCount

Get warning count from last operation

说明

public int <span class="methodname">mysql_xdevapi\SqlStatementResult::getWarningCounts ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

The number of warnings raised during the last CRUD operation.

范例

示例 #1 <span class="function">mysql_xdevapi\SqlStatementResult::getWarningsCount example

<?php

/* ... */

?>

SqlStatementResult::hasData

Check if result has data

说明

public bool <span class="methodname">mysql_xdevapi\SqlStatementResult::hasData ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

true if the result set has data.

范例

示例 #1 <span class="function">mysql_xdevapi\SqlStatementResult::hasData example

<?php

/* ... */

?>

SqlStatementResult::nextResult

Get next result

说明

public <span class="type">mysql_xdevapi\Result <span class="methodname">mysql_xdevapi\SqlStatementResult::nextResult ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

The next Result object from the result set.

范例

示例 #1 <span class="function">mysql_xdevapi\SqlStatementResult::nextResult example

<?php

/* ... */

?>

简介

类摘要

mysql_xdevapi\Statement

class mysql_xdevapi\Statement {

/* Constants */

const int mysql_xdevapi\Statement::EXECUTE_ASYNC = 1 ;

const int mysql_xdevapi\Statement::BUFFERED = 2 ;

/* 方法 */

public <span class="type">mysql_xdevapi\Result <span class="methodname">getNextResult ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\Result <span class="methodname">getResult ( <span class="methodparam">void )

public bool hasMoreResults ( <span class="methodparam">void )

}

预定义常量

mysql_xdevapi\Statement::EXECUTE_ASYNC

mysql_xdevapi\Statement::BUFFERED

Statement::__construct

Description constructor

说明

private <span class="methodname">mysql_xdevapi\Statement::__construct ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

范例

示例 #1 <span class="function">mysql_xdevapi\Statement::__construct example

<?php

/* ... */

?>

Statement::getNextResult

Get next result

说明

public <span class="type">mysql_xdevapi\Result <span class="methodname">mysql_xdevapi\Statement::getNextResult ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\Statement::getNextResult example

<?php

/* ... */

?>

Statement::getResult

Get result

说明

public <span class="type">mysql_xdevapi\Result <span class="methodname">mysql_xdevapi\Statement::getResult ( <span class="methodparam">void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\Statement::getResult example

<?php

/* ... */

?>

Statement::hasMoreResults

Check if more results

说明

public bool <span class="methodname">mysql_xdevapi\Statement::hasMoreResults ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

范例

示例 #1 <span class="function">mysql_xdevapi\Statement::hasMoreResults example

<?php

/* ... */

?>

简介

Provides access to the table through INSERT/SELECT/UPDATE/DELETE statements.

类摘要

mysql_xdevapi\Table

class mysql_xdevapi\Table <span class="oointerface">implements <span class="interfacename">mysql_xdevapi\SchemaObject {

/* 属性 */

public $name ;

/* 方法 */

public int <span class="methodname">count ( void )

public <span class="type">mysql_xdevapi\TableDelete <span class="methodname">delete ( void )

public bool existsInDatabase ( <span class="methodparam">void )

public string getName ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\Schema <span class="methodname">getSchema ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\Session <span class="methodname">getSession ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\TableInsert <span class="methodname">insert ( <span class="type">mixed $columns , <span class="methodparam">mixed $more_columns )

public bool isView ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">select ( <span class="type">mixed $columns , <span class="methodparam">mixed $more_columns )

public <span class="type">mysql_xdevapi\TableUpdate <span class="methodname">update ( void )

}

属性

name

Table::__construct

Table constructor

说明

private <span class="methodname">mysql_xdevapi\Table::__construct ( <span class="methodparam">void )

Construct a table object.

参数

此函数没有参数。

范例

示例 #1 <span class="function">mysql_xdevapi\Table::__construct example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");
?>

Table::count

Get row count

说明

public int <span class="methodname">mysql_xdevapi\Table::count ( <span class="methodparam">void )

Fetch the number of rows in the table.

参数

此函数没有参数。

返回值

The total number of rows in the table.

范例

示例 #1 mysql_xdevapi\Table::count example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

var_dump($table->count());
?>

以上例程会输出:

int(2)

Table::delete

Delete rows from table

说明

public <span class="type">mysql_xdevapi\TableDelete <span class="methodname">mysql_xdevapi\Table::delete ( <span class="methodparam">void )

Deletes rows from a table.

参数

此函数没有参数。

返回值

A TableDelete object; use the execute() method to execute the delete query.

范例

示例 #1 mysql_xdevapi\Table::delete example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$table->delete()->where("name = :name")->orderby("age DESC")->limit(1)->bind(['name' => 'John'])->execute();
?>

Table::existsInDatabase

Check if table exists in database

说明

public bool mysql_xdevapi\Table::existsInDatabase ( void )

Verifies if this table exists in the database.

参数

此函数没有参数。

返回值

Returns true if table exists in the database, else false if it does not.

范例

示例 #1 <span class="function">mysql_xdevapi\Table::existsInDatabase example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

if ($table->existsInDatabase()) {
  echo "Yes, this table still exists in the session's schema.";
}
?>

以上例程的输出类似于:

Yes, this table still exists in the session's schema.

Table::getName

Get table name

说明

public string mysql_xdevapi\Table::getName ( <span class="methodparam">void )

Returns the name of this database object.

参数

此函数没有参数。

返回值

The name of this database object.

范例

示例 #1 mysql_xdevapi\Table::getName example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

var_dump($table->getName());
?>

以上例程的输出类似于:

string(5) "names"

Table::getSchema

Get table schema

说明

public <span class="type">mysql_xdevapi\Schema <span class="methodname">mysql_xdevapi\Table::getSchema ( <span class="methodparam">void )

Fetch the schema associated with the table.

参数

此函数没有参数。

返回值

A Schema object.

范例

示例 #1 <span class="function">mysql_xdevapi\Table::getSchema example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

var_dump($table->getSchema());
?>

以上例程的输出类似于:

object(mysql_xdevapi\Schema)#9 (1) {
  ["name"]=>
  string(11) "addressbook"
}

Table::getSession

Get table session

说明

public <span class="type">mysql_xdevapi\Session <span class="methodname">mysql_xdevapi\Table::getSession ( <span class="methodparam">void )

Get session associated with the table.

参数

此函数没有参数。

返回值

A Session object.

范例

示例 #1 <span class="function">mysql_xdevapi\Table::getSession example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

var_dump($table->getSession());
?>

以上例程的输出类似于:

object(mysql_xdevapi\Session)#9 (0) {
}

Table::insert

Insert table rows

说明

public <span class="type">mysql_xdevapi\TableInsert <span class="methodname">mysql_xdevapi\Table::insert ( <span class="methodparam">mixed $columns , mixed $more_columns )

Inserts rows into a table.

参数

columns
The columns to insert data into. Can be an array with one or more values, or a string.

more_columns
Additional columns definitions.

返回值

A TableInsert object; use the execute() method to execute the insert statement.

范例

示例 #1 mysql_xdevapi\Table::insert example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$table ->insert("name", "age")
  ->values(["Suzanne", 31],["Julie", 43])
  ->execute();
?>

Table::isView

Check if table is view

说明

public bool mysql_xdevapi\Table::isView ( <span class="methodparam">void )

Determine if the underlying object is a view or not.

参数

此函数没有参数。

返回值

true if the underlying object is a view, otherwise false.

范例

示例 #1 mysql_xdevapi\Table::isView example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names

if ($table->isView()) {
    echo "This is a view.";
} else {
    echo "This is not a view.";
}
?>

以上例程会输出:

int(2)

Table::select

Select rows from table

说明

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">mysql_xdevapi\Table::select ( <span class="methodparam">mixed $columns , mixed $more_columns )

Fetches data from a table.

参数

columns
The columns to select data from. Can be an array with one or more values, or a string.

more_columns
Additional columns parameter definitions.

返回值

A TableSelect object; use the execute() method to execute the select and return a RowResult object.

范例

示例 #1 mysql_xdevapi\Table::count example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$row = $table->select('name', 'age')->execute()->fetchAll();

print_r($row);

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [name] => John
            [age] => 42
        )
    [1] => Array
        (
            [name] => Sam
            [age] => 33
        )
)

Table::update

Update rows in table

说明

public <span class="type">mysql_xdevapi\TableUpdate <span class="methodname">mysql_xdevapi\Table::update ( <span class="methodparam">void )

Updates columns in a table.

参数

此函数没有参数。

返回值

A TableUpdate object; use the execute() method to execute the update statement.

范例

示例 #1 mysql_xdevapi\Table::update example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$table->update()->set('age',34)->where('name = "Sam"')->limit(1)->execute();
?>

简介

A statement for delete operations on Table.

类摘要

mysql_xdevapi\TableDelete

class mysql_xdevapi\TableDelete implements <span class="interfacename">mysql_xdevapi\Executable {

/* 方法 */

public <span class="type">mysql_xdevapi\TableDelete <span class="methodname">bind ( <span class="type">array $placeholder_values )

public <span class="type">mysql_xdevapi\Result <span class="methodname">execute ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\TableDelete <span class="methodname">limit ( <span class="type">int $rows )

public <span class="type">mysql_xdevapi\TableDelete <span class="methodname">orderby ( <span class="type">string $orderby_expr )

public <span class="type">mysql_xdevapi\TableDelete <span class="methodname">where ( <span class="type">string $where_expr )

}

TableDelete::bind

Bind delete query parameters

说明

public <span class="type">mysql_xdevapi\TableDelete <span class="methodname">mysql_xdevapi\TableDelete::bind ( <span class="methodparam">array $placeholder_values )

Binds a value to a specific placeholder.

参数

placeholder_values
The name of the placeholder and the value to bind.

返回值

A TableDelete object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableDelete::bind example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$table->delete()
  ->where("name = :name")
  ->bind(['name' => 'John'])
  ->orderby("age DESC")
  ->limit(1)
  ->execute();

?>

TableDelete::__construct

TableDelete constructor

说明

private <span class="methodname">mysql_xdevapi\TableDelete::__construct ( void )

Initiated by using the delete() method.

参数

此函数没有参数。

范例

示例 #1 <span class="function">mysql_xdevapi\TableDelete::__construct example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$table->delete()
  ->where("name = :name")
  ->bind(['name' => 'John'])
  ->orderby("age DESC")
  ->limit(1)
  ->execute();

?>

TableDelete::execute

Execute delete query

说明

public <span class="type">mysql_xdevapi\Result <span class="methodname">mysql_xdevapi\TableDelete::execute ( <span class="methodparam">void )

Execute the delete query.

参数

此函数没有参数。

返回值

A Result object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableDelete::execute example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$table->delete()
  ->where("name = :name")
  ->bind(['name' => 'John'])
  ->orderby("age DESC")
  ->limit(1)
  ->execute();

?>

TableDelete::limit

Limit deleted rows

说明

public <span class="type">mysql_xdevapi\TableDelete <span class="methodname">mysql_xdevapi\TableDelete::limit ( <span class="methodparam">int $rows )

Sets the maximum number of records or documents to delete.

参数

rows
The maximum number of records or documents to delete.

返回值

TableDelete object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableDelete::limit example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$table->delete()
  ->where("name = :name")
  ->bind(['name' => 'John'])
  ->orderby("age DESC")
  ->limit(1)
  ->execute();

?>

TableDelete::orderby

Set delete sort criteria

说明

public <span class="type">mysql_xdevapi\TableDelete <span class="methodname">mysql_xdevapi\TableDelete::orderby ( <span class="methodparam">string $orderby_expr )

Set the order options for a result set.

参数

orderby_expr
The sort definition.

返回值

A TableDelete object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableDelete::orderBy example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$table->delete()
  ->where("age = :age")
  ->bind(['age' => 42])
  ->orderby("name DESC")
  ->limit(1)
  ->execute();

?>

TableDelete::where

Set delete search condition

说明

public <span class="type">mysql_xdevapi\TableDelete <span class="methodname">mysql_xdevapi\TableDelete::where ( <span class="methodparam">string $where_expr )

Sets the search condition to filter.

参数

where_expr
Define the search condition to filter documents or records.

返回值

TableDelete object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableDelete::where example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$table->delete()
  ->where("id = :id")
  ->bind(['id' => 42])
  ->limit(1)
  ->execute();

?>

简介

A statement for insert operations on Table.

类摘要

mysql_xdevapi\TableInsert

class mysql_xdevapi\TableInsert implements <span class="interfacename">mysql_xdevapi\Executable {

/* 方法 */

public <span class="type">mysql_xdevapi\Result <span class="methodname">execute ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\TableInsert <span class="methodname">values ( <span class="type">array $row_values )

}

TableInsert::__construct

TableInsert constructor

说明

private <span class="methodname">mysql_xdevapi\TableInsert::__construct ( void )

Initiated by using the insert() method.

参数

此函数没有参数。

范例

示例 #1 <span class="function">mysql_xdevapi\TableInsert::__construct example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$table
  ->insert("name", "age")
  ->values(["Suzanne", 31],["Julie", 43])
  ->execute();
?>

TableInsert::execute

Execute insert query

说明

public <span class="type">mysql_xdevapi\Result <span class="methodname">mysql_xdevapi\TableInsert::execute ( <span class="methodparam">void )

Execute the statement.

参数

此函数没有参数。

返回值

A Result object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableInsert::execute example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$table
  ->insert("name", "age")
  ->values(["Suzanne", 31],["Julie", 43])
  ->execute();
?>

TableInsert::values

Add insert row values

说明

public <span class="type">mysql_xdevapi\TableInsert <span class="methodname">mysql_xdevapi\TableInsert::values ( <span class="methodparam">array $row_values )

Set the values to be inserted.

参数

row_values
Values (an array) of columns to insert.

返回值

A TableInsert object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableInsert::values example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$table
  ->insert("name", "age")
  ->values(["Suzanne", 31],["Julie", 43])
  ->execute();
?>

简介

A statement for record retrieval operations on a Table.

类摘要

mysql_xdevapi\TableSelect

class mysql_xdevapi\TableSelect implements <span class="interfacename">mysql_xdevapi\Executable {

/* 方法 */

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">bind ( <span class="type">array $placeholder_values )

public <span class="type">mysql_xdevapi\RowResult <span class="methodname">execute ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">groupBy ( <span class="type">mixed $sort_expr )

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">having ( <span class="type">string $sort_expr )

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">limit ( <span class="type">int $rows )

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">lockExclusive ([ <span class="methodparam">int $lock_waiting_option ] )

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">lockShared ([ <span class="type">int $lock_waiting_option ] )

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">offset ( <span class="type">int $position )

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">orderby ( <span class="type">mixed $sort_expr , <span class="methodparam">mixed $sort_exprs )

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">where ( <span class="type">string $where_expr )

}

TableSelect::bind

Bind select query parameters

说明

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">mysql_xdevapi\TableSelect::bind ( <span class="methodparam">array $placeholder_values )

Binds a value to a specific placeholder.

参数

placeholder_values
The name of the placeholder, and the value to bind.

返回值

A TableSelect object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableSelect::bind example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$result = $table->select('name','age')
  ->where('name like :name and age > :age')
  ->bind(['name' => 'John', 'age' => 42])
  ->execute();

$row = $result->fetchAll();
print_r($row);
?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [name] => John
            [age] => 42
        )
)

TableSelect::__construct

TableSelect constructor

说明

private <span class="methodname">mysql_xdevapi\TableSelect::__construct ( void )

An object returned by the select() method; use execute() to execute the query.

参数

此函数没有参数。

范例

示例 #1 <span class="function">mysql_xdevapi\TableSelect::__construct example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 33)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$result = $table->select('name','age')
  ->where('name like :name and age > :age')
  ->bind(['name' => 'John', 'age' => 42])
  ->orderBy('age desc')
  ->execute();

$row = $result->fetchAll();
print_r($row);

?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [name] => John
            [age] => 42
        )
)

TableSelect::execute

Execute select statement

说明

public <span class="type">mysql_xdevapi\RowResult <span class="methodname">mysql_xdevapi\TableSelect::execute ( <span class="methodparam">void )

Execute the select statement by chaining it with the execute() method.

参数

此函数没有参数。

返回值

A RowResult object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableSelect::execute example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$result = $table->select('name','age')
  ->where('name like :name and age > :age')
  ->bind(['name' => 'John', 'age' => 42])
  ->orderBy('age desc')
  ->execute();

$row = $result->fetchAll();
?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [name] => John
            [age] => 42
        )
)

TableSelect::groupBy

Set select grouping criteria

说明

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">mysql_xdevapi\TableSelect::groupBy ( <span class="methodparam">mixed $sort_expr )

Sets a grouping criteria for the result set.

参数

sort_expr
The grouping criteria.

返回值

A TableSelect object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableSelect::groupBy example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 42)")->execute();
$session->sql("INSERT INTO addressbook.names values ('Suki', 31)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$result = $table->select('count(*) as count', 'age')
  ->groupBy('age')->orderBy('age asc')
  ->execute();

$row = $result->fetchAll();
print_r($row);
?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [count] => 1
            [age] => 31
        )
    [1] => Array
        (
            [count] => 2
            [age] => 42
        )
)

TableSelect::having

Set select having condition

说明

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">mysql_xdevapi\TableSelect::having ( <span class="methodparam">string $sort_expr )

Sets a condition for records to consider in aggregate function operations.

参数

sort_expr
A condition on the aggregate functions used on the grouping criteria.

返回值

A TableSelect object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableSelect::having example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 42)")->execute();
$session->sql("INSERT INTO addressbook.names values ('Suki', 31)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$result = $table->select('count(*) as count', 'age')
  ->groupBy('age')->orderBy('age asc')
  ->having('count > 1')
  ->execute();

$row = $result->fetchAll();
print_r($row);
?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [count] => 2
            [age] => 42
        )
)

TableSelect::limit

Limit selected rows

说明

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">mysql_xdevapi\TableSelect::limit ( <span class="methodparam">int $rows )

Sets the maximum number of records or documents to return.

参数

rows
The maximum number of records or documents.

返回值

A TableSelect object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableSelect::limit example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$result = $table->select('name', 'age')
  ->limit(1)
  ->execute();

$row = $result->fetchAll();
print_r($row);
?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [name] => John
            [age] => 42
        )
)

TableSelect::lockExclusive

Execute EXCLUSIVE LOCK

说明

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">mysql_xdevapi\TableSelect::lockExclusive ([ int $lock_waiting_option ] )

Execute a read operation with EXCLUSIVE LOCK. Only one lock can be active at a time.

参数

lock_waiting_option
The optional waiting option that defaults to MYSQLX_LOCK_DEFAULT. Valid values are:

  • MYSQLX_LOCK_DEFAULT

  • MYSQLX_LOCK_NOWAIT

  • MYSQLX_LOCK_SKIP_LOCKED

返回值

TableSelect object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableSelect::lockExclusive example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$session->startTransaction();

$result = $table->select('name', 'age')
  ->lockExclusive(MYSQLX_LOCK_NOWAIT)
  ->execute();

$session->commit();

$row = $result->fetchAll();
print_r($row);
?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [name] => John
            [age] => 42
        )
    [1] => Array
        (
            [name] => Sam
            [age] => 42
        )
)

TableSelect::lockShared

Execute SHARED LOCK

说明

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">mysql_xdevapi\TableSelect::lockShared ([ int $lock_waiting_option ] )

Execute a read operation with SHARED LOCK. Only one lock can be active at a time.

参数

lock_waiting_option
The optional waiting option that defaults to MYSQLX_LOCK_DEFAULT. Valid values are:

  • MYSQLX_LOCK_DEFAULT

  • MYSQLX_LOCK_NOWAIT

  • MYSQLX_LOCK_SKIP_LOCKED

返回值

A TableSelect object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableSelect::lockShared example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$session->startTransaction();

$result = $table->select('name', 'age')
  ->lockShared(MYSQLX_LOCK_NOWAIT)
  ->execute();

$session->commit();

$row = $result->fetchAll();
print_r($row);
?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [name] => John
            [age] => 42
        )
    [1] => Array
        (
            [name] => Sam
            [age] => 42
        )
)

TableSelect::offset

Set limit offset

说明

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">mysql_xdevapi\TableSelect::offset ( <span class="methodparam">int $position )

Skip given number of rows in result.

参数

position
The limit offset.

返回值

A TableSelect object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableSelect::offset example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$session->sql("DROP DATABASE IF EXISTS addressbook")->execute();
$session->sql("CREATE DATABASE addressbook")->execute();
$session->sql("CREATE TABLE addressbook.names(name text, age int)")->execute();
$session->sql("INSERT INTO addressbook.names values ('John', 42), ('Sam', 42)")->execute();

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$result = $table->select('name', 'age')
  ->limit(1)
  ->offset(1)
  ->execute();

$row = $result->fetchAll();
print_r($row);
?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [name] => Sam
            [age] => 42
        )
)

TableSelect::orderby

Set select sort criteria

说明

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">mysql_xdevapi\TableSelect::orderby ( <span class="methodparam">mixed $sort_expr , mixed $sort_exprs )

Sets the order by criteria.

参数

sort_expr
The expressions that define the order by criteria. Can be an array with one or more expressions, or a string.

sort_exprs
Additional sort_expr parameters.

返回值

A TableSelect object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableSelect::orderBy example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$result = $table->select('name', 'age')
  ->orderBy('name desc')
  ->execute();

$row = $result->fetchAll();
print_r($row);
?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [name] => Sam
            [age] => 42
        )
    [1] => Array
        (
            [name] => John
            [age] => 42
        )
)

TableSelect::where

Set select search condition

说明

public <span class="type">mysql_xdevapi\TableSelect <span class="methodname">mysql_xdevapi\TableSelect::where ( <span class="methodparam">string $where_expr )

Sets the search condition to filter.

参数

where_expr
Define the search condition to filter documents or records.

返回值

A TableSelect object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableSelect::where example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$result = $table->select('name','age')
  ->where('name like :name and age > :age')
  ->bind(['name' => 'John', 'age' => 42])
  ->execute();

$row = $result->fetchAll();
print_r($row);
?>

以上例程的输出类似于:

Array
(
    [0] => Array
        (
            [name] => John
            [age] => 42
        )
)

简介

A statement for record update operations on a Table.

类摘要

mysql_xdevapi\TableUpdate

class mysql_xdevapi\TableUpdate implements <span class="interfacename">mysql_xdevapi\Executable {

/* 方法 */

public <span class="type">mysql_xdevapi\TableUpdate <span class="methodname">bind ( <span class="type">array $placeholder_values )

public <span class="type">mysql_xdevapi\TableUpdate <span class="methodname">execute ( <span class="methodparam">void )

public <span class="type">mysql_xdevapi\TableUpdate <span class="methodname">limit ( <span class="type">int $rows )

public <span class="type">mysql_xdevapi\TableUpdate <span class="methodname">orderby ( <span class="type">mixed $orderby_expr , <span class="methodparam">mixed $orderby_exprs )

public <span class="type">mysql_xdevapi\TableUpdate <span class="methodname">set ( <span class="type">string $table_field , <span class="methodparam">string $expression_or_literal )

public <span class="type">mysql_xdevapi\TableUpdate <span class="methodname">where ( <span class="type">string $where_expr )

}

TableUpdate::bind

Bind update query parameters

说明

public <span class="type">mysql_xdevapi\TableUpdate <span class="methodname">mysql_xdevapi\TableUpdate::bind ( <span class="methodparam">array $placeholder_values )

Binds a value to a specific placeholder.

参数

placeholder_values
The name of the placeholder, and the value to bind, defined as a JSON array.

返回值

A TableUpdate object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableUpdate::bind example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$table->update()
  ->set('status', 'admin')
  ->where('name = :name and age > :age')
  ->bind(['name' => 'Bernie', 'age' => 2000])
  ->execute();

?>

TableUpdate::__construct

TableUpdate constructor

说明

private <span class="methodname">mysql_xdevapi\TableUpdate::__construct ( void )

Initiated by using the update() method.

参数

此函数没有参数。

范例

示例 #1 <span class="function">mysql_xdevapi\TableUpdate::__construct example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$res = $table->update()
  ->set('level', 3)
  ->where('age > 15 and age < 22')
  ->limit(4)
  ->orderby(['age asc','name desc'])
  ->execute();

?>

TableUpdate::execute

Execute update query

说明

public <span class="type">mysql_xdevapi\TableUpdate <span class="methodname">mysql_xdevapi\TableUpdate::execute ( <span class="methodparam">void )

Executes the update statement.

参数

此函数没有参数。

返回值

A TableUpdate object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableUpdate::execute example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$res = $table->update()
  ->set('level', 3)
  ->where('age > 15 and age < 22')
  ->limit(4)
  ->orderby(['age asc','name desc'])
  ->execute();

?>

TableUpdate::limit

Limit update row count

说明

public <span class="type">mysql_xdevapi\TableUpdate <span class="methodname">mysql_xdevapi\TableUpdate::limit ( <span class="methodparam">int $rows )

Set the maximum number of records or documents update.

参数

rows
The maximum number of records or documents to update.

返回值

A TableUpdate object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableUpdate::limit example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$res = $table->update()
  ->set('level', 3)
  ->where('age > 15 and age < 22')
  ->limit(4)
  ->orderby(['age asc','name desc'])
  ->execute();

?>

TableUpdate::orderby

Set sorting criteria

说明

public <span class="type">mysql_xdevapi\TableUpdate <span class="methodname">mysql_xdevapi\TableUpdate::orderby ( <span class="methodparam">mixed $orderby_expr , <span class="type">mixed $orderby_exprs )

Sets the sorting criteria.

参数

orderby_expr
The expressions that define the order by criteria. Can be an array with one or more expressions, or a string.

orderby_exprs
Additional sort_expr parameters.

返回值

TableUpdate object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableUpdate::orderby example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$res = $table->update()
  ->set('level', 3)
  ->where('age > 15 and age < 22')
  ->limit(4)
  ->orderby(['age asc','name desc'])
  ->execute();
?>

TableUpdate::set

Add field to be updated

说明

public <span class="type">mysql_xdevapi\TableUpdate <span class="methodname">mysql_xdevapi\TableUpdate::set ( <span class="methodparam">string $table_field , <span class="type">string $expression_or_literal )

Updates the column value on records in a table.

参数

table_field
The column name to be updated.

expression_or_literal
The value to be set on the specified column.

返回值

TableUpdate object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableUpdate::set example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$res = $table->update()
  ->set('level', 3)
  ->where('age > 15 and age < 22')
  ->limit(4)
  ->orderby(['age asc','name desc'])
  ->execute();

?>

TableUpdate::where

Set search filter

说明

public <span class="type">mysql_xdevapi\TableUpdate <span class="methodname">mysql_xdevapi\TableUpdate::where ( <span class="methodparam">string $where_expr )

Set the search condition to filter.

参数

where_expr
The search condition to filter documents or records.

返回值

A TableUpdate object.

范例

示例 #1 <span class="function">mysql_xdevapi\TableUpdate::where example

<?php
$session = mysql_xdevapi\getSession("mysqlx://user:password@localhost");

$schema = $session->getSchema("addressbook");
$table  = $schema->getTable("names");

$res = $table->update()
  ->set('level', 3)
  ->where('age > 15 and age < 22')
  ->limit(4)
  ->orderby(['age asc','name desc'])
  ->execute();

?>

简介

类摘要

mysql_xdevapi\Warning

class mysql_xdevapi\Warning {

/* 属性 */

public $message ;

public $level ;

public $code ;

/* Constructor */

private <span class="methodname">__construct ( <span class="methodparam">void )

}

属性

message

level

code

Warning::__construct

Warning constructor

说明

private <span class="methodname">mysql_xdevapi\Warning::__construct ( <span class="methodparam">void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

范例

示例 #1 <span class="function">mysql_xdevapi\Warning::__construct example

<?php

/* ... */

?>

原始的 MySQL API

目录

从 PHP 5.5.0 起这个扩展已经被废弃,并且从 PHP 7.0.0. 开始被移除。作为替代,可以使用 mysqli 或者 PDO_MySQL 扩展代替。 参见 MySQL API 概览 寻找关于选择 MySQL API 的更多帮助。

这些函数允许你接入 MySQL 数据库服务器。更多关于 MySQL 的信息: » http://www.mysql.com/

关于 MySQL 的文档能在此找到: » http://dev.mysql.com/doc/

安装/配置

目录

需求

为了使这些函数能够使用,你必须编译加入 PHP 对 MySQL 的支持。

Warning

本扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。应使用 MySQLiPDO_MySQL 扩展来替换之。参见 MySQL:选择 API 指南以及相关 FAQ 来获取更多信息。用以替代本函数的有:

安装

Warning

本扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。应使用 MySQLiPDO_MySQL 扩展来替换之。参见 MySQL:选择 API 指南以及相关 FAQ 来获取更多信息。用以替代本函数的有:

编译时,只要使用 --with-mysql[=DIR] 配置选项即可,其中可选的 [DIR] 指向 MySQL 的安装目录。

虽然本 MySQL 扩展库兼容 MySQL 4.1.0 及其以后版本,但是它不支持这些版本提供的额外功能。要使用这些功能,请使用 MySQLi 扩展库。

如果要同时安装 mysql 扩展库和 mysqli 扩展库,必须使用同一个客户端库以避免任何冲突。

在 Linux 系统下安装

Note: [DIR] is the path to the MySQL client library files (headers and libraries), which can be downloaded from » MySQL.

PHP 版本 默认 配置选项: mysqlnd 配置选项: libmysql 更新日志
4.x.x libmysql 不适用 --without-mysql to disable MySQL enabled by default, MySQL client libraries are bundled
5.0.x, 5.1.x, 5.2.x libmysql 不适用 --with-mysql=[DIR] MySQL is no longer enabled by default, and the MySQL client libraries are no longer bundled
5.3.x libmysql --with-mysql=mysqlnd --with-mysql=[DIR] mysqlnd is now available
5.4.x mysqlnd --with-mysql --with-mysql=[DIR] mysqlnd is now the default

在 Windows 系统下安装

PHP 4

PHP MySQL 扩展已经编译入 PHP。

PHP 5+

MySQL 默认未启用,因此必须在 php.ini 中激活 php_mysql.dll 动态连接库。此外,PHP 还需要访问 MySQL 客户端连接库。PHP 的 Windows 发行版包括了一个 libmysql.dll,为了让 PHP 能和 MySQL 对话,此文件必须放在 Windows 的系统路径 PATH 中。怎样做见 FAQ 中的“怎样把 PHP 目录加入到 Windows PATH”。尽管将 libmysql.dll 拷贝到 Windows 系统目录中也可以(因为系统目录默认在系统路径 PATH 中),但不推荐这样做。

要激活任何 PHP 扩展库(例如 php_mysql.dll),PHP 指令 extension_dir 要被设为 PHP 扩展库所在的目录。参见手工 Windows 安装指南。PHP 5 下 extension_dir 取值的一个例子是 c:\php\ext

Note:

如果启动 web 服务器时出现类似如下的错误:"Unable to load dynamic library './php_mysql.dll'",这是因为系统找不到 php_mysql.dll 和/或 libmysql.dll

PHP 5.3.0+

The MySQL Native Driver is enabled by default. Include php_mysql.dll, but libmysql.dll is no longer required or used.

MySQL 安装注意事项

Warning

当同时加在本扩展库和 recode 扩展库时 PHP 可能会崩溃。更多信息见 recode 扩展库。

Note:

如果需要不同于 latin(默认值)的字符集,必须安装外部的(非绑定的)已编译入所需字符集支持的 libmysql。

运行时配置

这些函数的行为受 php.ini 中的设置影响。

名字 默认 可修改范围 更新日志
mysql.allow_local_infile "1" PHP_INI_SYSTEM  
mysql.allow_persistent "1" PHP_INI_SYSTEM  
mysql.max_persistent "-1" PHP_INI_SYSTEM  
mysql.max_links "-1" PHP_INI_SYSTEM  
mysql.trace_mode "0" PHP_INI_ALL 自 PHP 4.3.0 起可用
mysql.default_port NULL PHP_INI_ALL  
mysql.default_socket NULL PHP_INI_ALL 自 PHP 4.0.1 起可用
mysql.default_host NULL PHP_INI_ALL  
mysql.default_user NULL PHP_INI_ALL  
mysql.default_password NULL PHP_INI_ALL  
mysql.connect_timeout "60" PHP_INI_ALL 自 PHP 4.3.0 起可用。在 PHP \<= 4.3.2 时为 PHP_INI_SYSTEM

有关 PHP_INI_* 样式的更多详情与定义,见 配置可被设定范围

这是配置指令的简短说明。

mysql.allow_local_infile integer
Allow accessing, from PHP's perspective, local files with LOAD DATA statements

mysql.allow_persistent boolean
是否允许 MySQL 的持久连接

mysql.max_persistent integer
每个进程中最大的持久连接数目。

mysql.max_links integer
每个进程中最大的连接数,包括持久连接。

mysql.trace_mode boolean
跟踪模式。当激活 mysql.trace_mode 时,将会显示 table/index 扫描的警告,未释放的结果集以及 SQL 错误。(PHP 4.3.0 引进)

mysql.default_port string
指定默认连接数据库的 TCP 端口号。如果没有指定默认端口号,则按顺序从 MYSQL_TCP_PORT 环境变量,/etc/services 文件中的 mysql-tcp 项或者编译时指定的 MYSQL_PORT 常量中取得。Win32 环境下只会使用 MYSQL_PORT 常量。

mysql.default_socket string
当使用本地连接的时候,默认的 socket 名称。

mysql.default_host string
默认连接的数据库服务器地址。不适用于 SQL 安全模式

mysql.default_user string
默认连接数据库时使用的用户名。不适用于 SQL 安全模式

mysql.default_password string
默认连接数据库时使用的密码。不适用于 SQL 安全模式

mysql.connect_timeout integer
连接超时秒数。在 Linux 中,此参数设定了等候来自服务器的响应的时长。

资源类型

在 MySQL 模块中用到了两种资源类型。第一种是数据库链接的链接标识符,第二种是资源标识符,包含了查询结果集。

更新日志

对本扩展的类/函数/方法有以下更新。

ext/mysql 扩展相关的更新日志。

以下列表是整个 ext/mysql 扩展的变动更新。

版本 说明
7.0.0

此扩展从 PHP 中移除. 参见 .

5.5.0

此扩展已经不建议使用。通过 mysql_connectmysql_pconnect 或任何由 mysql_* 函数实现的 MySQL 数据库连接 将产生 E_DEPRECATED 错误。

5.5.0

所有旧的废弃函数和别名现在会产生 E_DEPRECATED 错误。这些函数分别是:

mysql(), mysql_fieldname(), mysql_fieldtable(), mysql_fieldlen(), mysql_fieldtype(), mysql_fieldflags(), mysql_selectdb(), mysql_createdb(), mysql_dropdb(), mysql_freeresult(), mysql_numfields(), mysql_numrows(), mysql_listdbs(), mysql_listtables(), mysql_listfields(), mysql_db_name(), mysql_dbname(), mysql_tablename() 和 mysql_table_name()。

以下列表为 ext/mysql 函数完整的更新历史项。

预定义常量

下列常量由此扩展定义,且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

在 PHP 4.3.0 以后的版本中,允许在 <span class="function">mysql_connect 函数和 <span class="function">mysql_pconnect 函数中指定更多的客户端标记。下面列出所定义的常量:

常量 说明
MYSQL_CLIENT_COMPRESS 使用压缩的通讯协议
MYSQL_CLIENT_IGNORE_SPACE 允许在函数名后留空格位
MYSQL_CLIENT_INTERACTIVE 允许设置断开连接之前所空闲等候的 interactive_timeout 时间(代替 wait_timeout)。
MYSQL_CLIENT_SSL 使用 SSL 加密。本标志仅在 MySQL 客户端库版本为 4.x 或更高版本时可用。在 PHP 4 和 Windows 版的 PHP 5 安装包中绑定的都是 3.23.x。

mysql_fetch_array 函数使用一个常量来表示所返回数组的类型。下面是常量的定义:

常量 说明
MYSQL_ASSOC 返回的数据列使用字段名作为数组的索引名。
MYSQL_BOTH 返回的数据列使用字段名及数字索引作为数组的索引名。
MYSQL_NUM 返回的数据列使用数字索引作为数组的索引名。索引从 0 开始,表示返回结果的第一个字段。

范例

目录

MySQL 扩展概述范例

这个简单的范例展示了如何连接、执行一个查询,打印结果集后断开 MySQL 数据库的连接。

示例 #1 MySQL 扩展概述范例

<?php
// 连接、选择数据库
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
    or die('Could not connect: ' . mysql_error());
echo 'Connected successfully';
mysql_select_db('my_database') or die('Could not select database');

// 执行 SQL 查询
$query = 'SELECT * FROM my_table';
$result = mysql_query($query) or die('Query failed: ' . mysql_error());

// 以 HTML 打印查询结果
echo "<table>\n";
while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) {
    echo "\t<tr>\n";
    foreach ($line as $col_value) {
        echo "\t\t<td>$col_value</td>\n";
    }
    echo "\t</tr>\n";
}
echo "</table>\n";

// 释放结果集
mysql_free_result($result);

// 关闭连接
mysql_close($link);
?>

注释

Note:

大多数 MySQL 函数的最后一个可选参数是 link_identifier。 如果没有提供这个参数,则会使用最后一个打开的连接。 若不存在这个最后打开的连接,则会尝试用 php.ini 里定义的默认参数来连接。 如果没有成功连接,函数会返回 false

mysql_affected_rows

取得前一次 MySQL 操作所影响的记录行数

Warning

本扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。应使用 MySQLiPDO_MySQL 扩展来替换之。参见 MySQL:选择 API 指南以及相关 FAQ 来获取更多信息。用以替代本函数的有:

  • mysqli_affected_rows
  • PDOStatement::rowCount

说明

int <span class="methodname">mysql_affected_rows ([ <span class="methodparam">resource $link_identifier = NULL ] )

取得最近一次与 link_identifier 关联的 INSERT,UPDATE 或 DELETE 查询所影响的记录行数。

参数

link_identifier
MySQL 连接。如不指定连接标识,则使用由 <span class="function">mysql_connect 最近打开的连接。如果没有找到该连接,会尝试不带参数调用 <span class="function">mysql_connect 来创建。如没有找到连接或无法建立连接,则会生成 E_WARNING 级别的错误。

返回值

执行成功则返回受影响的行的数目,如果最近一次查询失败的话,函数返回 -1。

如果最近一次操作是没有任何条件(WHERE)的 DELETE 查询,在表中所有的记录都会被删除,但本函数返回值在 4.1.2 版之前都为 0。

当使用 UPDATE 查询,MySQL 不会将原值和新值一样的列更新。这样使得 <span class="function">mysql_affected_rows 函数返回值不一定就是查询条件所符合的记录数,只有真正被修改的记录数才会被返回。

REPLACE 语句首先删除具有相同主键的记录,然后插入一个新记录。本函数返回的是被删除的记录数加上被插入的记录数。

"INSERT ... ON DUPLICATE KEY UPDATE" 这种情况的查询,当执行了一次 INSERT 返回的值会是 1;如果是对已经存在的记录执行一次 UPDATE 将返回 2

范例

示例 #1 mysql_affected_rows 例子

<?php
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
    die('Could not connect: ' . mysql_error());
}
mysql_select_db('mydb');

/* 本例返回被删除记录的准确数目 */
mysql_query('DELETE FROM mytable WHERE id < 10');
printf("Records deleted: %d\n", mysql_affected_rows());

/* 对于非真值的 WHERE 子句,应返回 0 */
mysql_query('DELETE FROM mytable WHERE 0');
printf("Records deleted: %d\n", mysql_affected_rows());
?>

以上例程的输出类似于:

Records deleted: 10
Records deleted: 0

示例 #2 使用事务处理的 <span class="function">mysql_affected_rows 例子

<?php
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
    die('Could not connect: ' . mysql_error());
}
mysql_select_db('mydb');

/* Update records */
mysql_query("UPDATE mytable SET used=1 WHERE id < 10");
printf ("Updated records: %d\n", mysql_affected_rows());
mysql_query("COMMIT");
?>

以上例程的输出类似于:

Updated Records: 10

注释

Note: 事务处理

如果使用事务处理(transactions),需要在 INSERT,UPDATE 或 DELETE 查询后调用 mysql_affected_rows 函数,而不是在 COMMIT 命令之后。

Note: SELECT 语句

要获取 SELECT 所返回的行数,可以用 <span class="function">mysql_num_rows。

Note: Cascaded 外键

mysql_affected_rows does not count rows affected implicitly through the use of ON DELETE CASCADE and/or ON UPDATE CASCADE in foreign key constraints.

参见

  • mysql_num_rows
  • mysql_info

mysql_client_encoding

返回字符集的名称

说明

string <span class="methodname">mysql_client_encoding ([ <span class="methodparam">resource $link_identifier ] )

从 MySQL 中取得 character_set 变量的值。

参数

link_identifier
MySQL 连接。如不指定连接标识,则使用由 <span class="function">mysql_connect 最近打开的连接。如果没有找到该连接,会尝试不带参数调用 <span class="function">mysql_connect 来创建。如没有找到连接或无法建立连接,则会生成 E_WARNING 级别的错误。

返回值

返回当前连接的默认字符集名称。

范例

示例 #1 mysql_client_encoding 例子

<?php
$link    = mysql_connect('localhost', 'mysql_user', 'mysql_password');
$charset = mysql_client_encoding($link);

echo "The current character set is: $charset\n";
?>

以上例程的输出类似于:

The current character set is: latin1

注释

Note:

本扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。应使用 MySQLiPDO_MySQL 扩展来替换之。参见 MySQL:选择 API 指南以及相关 FAQ 来获取更多信息。用以替代本函数的有:

  • mysqli_character_set_name
  • PDO::setAttribute (e.g., $db->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8'");)

参见

  • mysql_real_escape_string

mysql_close

关闭 MySQL 连接

Warning

本扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。应使用 MySQLiPDO_MySQL 扩展来替换之。参见 MySQL:选择 API 指南以及相关 FAQ 来获取更多信息。用以替代本函数的有:

  • mysqli_close
  • PDO: 为 PDO 对象设置一个 null

说明

bool <span class="methodname">mysql_close ([ <span class="methodparam">resource $link_identifier = NULL ] )

mysql_close 关闭指定的连接标识所关联的到 MySQL 服务器的非持久连接。如果没有指定 link_identifier,则关闭上一个打开的连接。

通常不需要使用 <span class="function">mysql_close,因为已打开的非持久连接会在脚本执行完毕后自动关闭。参见释放资源

参数

link_identifier
MySQL 连接. 如果该连接标识符未给出, 将使用最近一次<span class="function">mysql_connect建立的连接. 如果没有找到可使用的连接, 将产生一个 E_WARNING 错误.

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 mysql_close 例子

<?php
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
    die('Could not connect: ' . mysql_error());
}
echo 'Connected successfully';
mysql_close($link);
?>

以上例程会输出:

Connected successfully

注释

Note:

mysql_close 不会关闭由 <span class="function">mysql_pconnect 建立的持久连接。

参见

  • mysql_connect
  • mysql_free_result

mysql_connect

打开一个到 MySQL 服务器的连接

Warning

本扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。应使用 MySQLiPDO_MySQL 扩展来替换之。参见 MySQL:选择 API 指南以及相关 FAQ 来获取更多信息。用以替代本函数的有:

  • mysqli_connect
  • PDO::__construct

说明

resource <span class="methodname">mysql_connect ([ <span class="methodparam">string $server [, string $username [, <span class="type">string $password [, <span class="methodparam">bool $new_link [, int $client_flags ]]]]] )

打开或重复使用一个到 MySQL 服务器的连接。

参数

server
MySQL 服务器。可以包括端口号,例如 "hostname:port",或者到本地套接字的路径,例如对于 localhost 的 ":/path/to/socket"。

如果 PHP 指令 mysql.default_host 未定义(默认情况),则默认值是 'localhost:3306'。 在 SQL 安全模式 时,参数被忽略,总是使用 'localhost:3306'。

username
用户名。默认值由 mysql.default_user 定义。 在 SQL 安全模式 时,参数被忽略,总是使用服务器进程所有者的用户名。

password
密码。默认值由mysql.default_password定义。在 SQL 安全模式 时,参数被忽略,总是使用空密码。

new_link
如果用同样的参数第二次调用 <span class="function">mysql_connect,将不会建立新连接,而将返回已经打开的连接标识。参数 new_link 改变此行为并使 mysql_connect 总是打开新的连接,甚至当 mysql_connect 曾在前面被用同样的参数调用过。

client_flags
client_flags 参数可以是以下常量的组合:MYSQL_CLIENT_SSLMYSQL_CLIENT_COMPRESSMYSQL_CLIENT_IGNORE_SPACEMYSQL_CLIENT_INTERACTIVE。进一步信息见

返回值

如果成功则返回一个 MySQL 连接标识, 或者在失败时返回 false

更新日志

版本 说明
4.3.0 添加 client_flags 参数。
4.2.0 添加 new_link 参数。
3.0.10 server 添加 ":/path/to/socket" 支持。
3.0.0 server 添加 ":port" 支持。

范例

示例 #1 mysql_connect 例子

<?php
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
    die('Could not connect: ' . mysql_error());
}
echo 'Connected successfully';
mysql_close($link);
?>

示例 #2 mysql_connect 例子:使用 hostname:port 语法

<?php
// we connect to example.com and port 3307
$link = mysql_connect('example.com:3307', 'mysql_user', 'mysql_password');
if (!$link) {
    die('Could not connect: ' . mysql_error());
}
echo 'Connected successfully';
mysql_close($link);

// we connect to localhost at port 3307
$link = mysql_connect('127.0.0.1:3307', 'mysql_user', 'mysql_password');
if (!$link) {
    die('Could not connect: ' . mysql_error());
}
echo 'Connected successfully';
mysql_close($link);
?>

示例 #3 mysql_connect 例子:使用 ":/path/to/socket" 语法

<?php
// we connect to localhost and socket e.g. /tmp/mysql.sock

//variant 1: ommit localhost
$link = mysql_connect('/tmp/mysql', 'mysql_user', 'mysql_password');
if (!$link) {
    die('Could not connect: ' . mysql_error());
}
echo 'Connected successfully';
mysql_close($link);


// variant 2: with localhost
$link = mysql_connect('localhost:/tmp/mysql.sock', 'mysql_user', 'mysql_password');
if (!$link) {
    die('Could not connect: ' . mysql_error());
}
echo 'Connected successfully';
mysql_close($link);
?>

注释

Note:

本扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。应使用 MySQLiPDO_MySQL 扩展来替换之。参见 MySQL:选择 API 指南以及相关 FAQ 来获取更多信息。用以替代本函数的有:

  • mysqli_connect
  • PDO::__construct

Note:

只要将 server 指定为 "localhost" 或 "localhost:port",MySQL 客户端库会越过此值并尝试连接到本地套接字(Windows 中的名字管道)。如果想用 TCP/IP,应该用 "127.0.0.1" 代替 "localhost"。如果 MySQL 客户端库试图连接到一个错误的本地套接字,则应该在 PHP 配置中设定 的正确路径并把 server 留空。

Note:

脚本一结束,到服务器的连接就被关闭,除非之前已经明确调用 <span class="function">mysql_close 关闭了。

Note:

可以在函数名前加上一个 @ 来抑制出错时的错误信息。

参见

  • mysql_pconnect
  • mysql_close

mysql_create_db

新建一个 MySQL 数据库

说明

bool <span class="methodname">mysql_create_db ( <span class="methodparam">string $database name [, <span class="type">resource $link_identifier ] )

mysql_create_db 尝试在指定的连接标识所关联的服务器上建立一个新数据库。

参数

database_name
要创建的数据库名。

link_identifier
MySQL 连接。如不指定连接标识,则使用由 <span class="function">mysql_connect 最近打开的连接。如果没有找到该连接,会尝试不带参数调用 <span class="function">mysql_connect 来创建。如没有找到连接或无法建立连接,则会生成 E_WARNING 级别的错误。

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 替代 mysql_create_db 的例子

mysql_create_db 函数已废弃。最好用 <span class="function">mysql_query 来提交一条 SQL 的 CREATE DATABASE 语句来代替。

<?php
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
    die('Could not connect: ' . mysql_error());
}

$sql = 'CREATE DATABASE my_db';
if (mysql_query($sql, $link)) {
    echo "Database my_db created successfully\n";
} else {
    echo 'Error creating database: ' . mysql_error() . "\n";
}
?>

以上例程的输出类似于:

Database my_db created successfully

注释

Note:

本扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。应使用 MySQLiPDO_MySQL 扩展来替换之。参见 MySQL:选择 API 指南以及相关 FAQ 来获取更多信息。用以替代本函数的有:

  • mysqli_query
  • PDO::query

Note:

为了向下兼容,可以使用下列已废弃的别名: <span class="function">mysql_createdb

Note:

如果 MySQL 扩展是基于 MySQL 4.x 客户端库编译的话则本函数不可用。

参见

  • mysql_query
  • mysql_select_db

mysql_data_seek

移动内部结果的指针

说明

bool <span class="methodname">mysql_data_seek ( <span class="methodparam">resource $result , int $row_number )

mysql_data_seek 将指定的结果标识所关联的 MySQL 结果内部的行指针移动到指定的行号。接着调用 <span class="function">mysql_fetch_row 将返回那一行。

row_number 从 0 开始。row_number 的取值范围应该从 0 到 mysql_num_rows - 1。但是如果结果集为空(<span class="function">mysql_num_rows == 0),要将指针移动到 0 会失败并发出 E_WARNING 级的错误,<span class="function">mysql_data_seek 将返回 false

参数

result
resource 型的结果集。此结果集来自对 <span class="function">mysql_query 的调用。

row_number
想要设定的新的结果集指针的行数。

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 mysql_data_seek 例子

<?php
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
    die('Could not connect: ' . mysql_error());
}
$db_selected = mysql_select_db('sample_db');
if (!$db_selected) {
    die('Could not select database: ' . mysql_error());
}
$query = 'SELECT last_name, first_name FROM friends';
$result = mysql_query($query);
if (!$result) {
    die('Query failed: ' . mysql_error());
}
/* fetch rows in reverse order */
for ($i = mysql_num_rows($result) - 1; $i >= 0; $i--) {
    if (!mysql_data_seek($result, $i)) {
        echo "Cannot seek to row $i: " . mysql_error() . "\n";
        continue;
    }

    if (!($row = mysql_fetch_assoc($result))) {
        continue;
    }

    echo $row['last_name'] . ' ' . $row['first_name'] . "<br />\n";
}

mysql_free_result($result);
?>

注释

Note:

本扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。应使用 MySQLiPDO_MySQL 扩展来替换之。参见 MySQL:选择 API 指南以及相关 FAQ 来获取更多信息。用以替代本函数的有:

  • mysqli_data_seek
  • PDO::FETCH_ORI_ABS

Note:

mysql_data_seek 只能和 <span class="function">mysql_query 结合起来使用,而不能用于 <span class="function">mysql_unbuffered_query。

参见

  • mysql_query
  • mysql_num_rows
  • mysql_fetch_row
  • mysql_fetch_assoc
  • mysql_fetch_array
  • mysql_fetch_object

mysql_db_name

取得结果数据

说明

string <span class="methodname">mysql_db_name ( <span class="methodparam">resource $result , int $row [, mixed $field ] )

取得 mysql_list_dbs 调用所返回的数据库名。

参数

result
mysql_list_dbs 调用所返回的结果指针。

row
结果集中的行号。

field
字段名。

返回值

如果成功则返回数据库名,失败返回 false。如果返回了 false,用 mysql_error 来判断错误的种类。

范例

示例 #1 mysql_db_name 例子

<?php
error_reporting(E_ALL);

$link = mysql_connect('dbhost', 'username', 'password');
$db_list = mysql_list_dbs($link);

$i = 0;
$cnt = mysql_num_rows($db_list);
while ($i < $cnt) {
    echo mysql_db_name($db_list, $i) . "\n";
    $i++;
}
?>

注释

Note:

本扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。应使用 MySQLiPDO_MySQL 扩展来替换之。参见 MySQL:选择 API 指南以及相关 FAQ 来获取更多信息。用以替代本函数的有:

  • Query: SELECT DATABASE()

Note:

为了向下兼容,可以使用下列已废弃的别名: <span class="function">mysql_dbname

参见

  • mysql_list_dbs
  • mysql_tablename

mysql_db_query

发送一条 MySQL 查询

说明

resource <span class="methodname">mysql_db_query ( <span class="methodparam">string $database , string $query [, <span class="type">resource $ link_identifier ] )

根据查询结果返回一个正的 MySQL 结果资源号,出错时返回 false。本函数会对 INSERT/UPDATE/DELETE 查询返回 true/false 来指示成功或失败。

mysql_db_query 选择一个数据库并在其上执行查询。如果没有提供可选的连接标识,本函数会去找一个到 MySQL 服务器的已打开的连接,如果找不到已打开连接则会尝试无参数调用 <span class="function">mysql_connect 来建立一个。

注意此函数不会切换回先前连接到的数据库。换句话说,不能用此函数临时在另一个数据库上执行 sql 查询,只能手工切换回来。强烈建议用户在 sql 查询中使用 database.table 语法来替代此函数。

参见 mysql_connect 和 <span class="function">mysql_query。

Note: 自 PHP 4.0.6 起不提倡使用此函数。不要用此函数,用 <span class="function">mysql_select_db 和 <span class="function">mysql_query 来替代。

mysql_drop_db

丢弃(删除)一个 MySQL 数据库

说明

bool <span class="methodname">mysql_drop_db ( <span class="methodparam">string $database_name [, <span class="type">resource $ link_identifier ] )

mysql_drop_db 尝试丢弃(删除)指定连接标识所关联的服务器上的一整个数据库。

成功时返回 true, 或者在失败时返回 false

为向下兼容也可以用 <span class="function">mysql_dropdb,但反对这样做。

Note:

不提倡使用 mysql_drop_db 函数。最好用 mysql_query 提交一条 SQL DROP DATABASE 语句来替代。

Warning

如果 MySQL 扩展库是基于 MySQL 4.x 客户端库建立的,则本函数不可用。

参见 mysql_create_db 和 <span class="function">mysql_query。

参数

database_name
The name of the database that will be deleted.

link_identifier
MySQL 连接。如不指定连接标识,则使用由 <span class="function">mysql_connect 最近打开的连接。如果没有找到该连接,会尝试不带参数调用 <span class="function">mysql_connect 来创建。如没有找到连接或无法建立连接,则会生成 E_WARNING 级别的错误。

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 mysql_drop_db alternative example

<?php
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
    die('Could not connect: ' . mysql_error());
}

$sql = 'DROP DATABASE my_db';
if (mysql_query($sql, $link)) {
    echo "Database my_db was successfully dropped\n";
} else {
    echo 'Error dropping database: ' . mysql_error() . "\n";
}
?>

注释

Note:

本扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。应使用 MySQLiPDO_MySQL 扩展来替换之。参见 MySQL:选择 API 指南以及相关 FAQ 来获取更多信息。用以替代本函数的有:

  • Execute a DROP DATABASE query

Warning

This function will not be available if the MySQL extension was built against a MySQL 4.x client library.

Note:

为了向下兼容,可以使用下列已废弃的别名: <span class="function">mysql_dropdb

参见

  • mysql_query

mysql_errno

返回上一个 MySQL 操作中的错误信息的数字编码

说明

int <span class="methodname">mysql_errno ([ <span class="methodparam">resource $link_identifier ] )

返回上一个 MySQL 函数的错误号码,如果没有出错则返回 0(零)。

从 MySQL 数据库后端来的错误不再发出警告,要用 <span class="function">mysql_errno 来提取错误代码。注意本函数仅返回最近一次 MySQL 函数的执行(不包括 <span class="function">mysql_error 和 <span class="function">mysql_errno)的错误代码,因此如果要使用此函数,确保在调用另一个 MySQL 函数之前检查它的值。

示例 #1 mysql_errno 例子

<?php
    mysql_connect("localhost", "mysql_user", "mysql_password");

    mysql_select_db("nonexistentdb");
    echo mysql_errno() . ": " . mysql_error(). "\n";

    mysql_select_db("kossu");
    mysql_query("SELECT * FROM nonexistenttable");
    echo mysql_errno() . ": " . mysql_error() . "\n";
?>

以上例子将产生如下输出:

1049: Unknown database 'nonexistentdb'
1146: Table 'kossu.nonexistenttable' doesn't exist

Note:

如果指定了可选参数则用给定的连接提取错误代码。否则使用上一个打开的连接。

参见 mysql_error

mysql_error

返回上一个 MySQL 操作产生的文本错误信息

说明

string <span class="methodname">mysql_error ([ <span class="methodparam">resource $link_identifier ] )

返回上一个 MySQL 函数的错误文本,如果没有出错则返回 ''(空字符串)。如果没有指定连接资源号,则使用上一个成功打开的连接从 MySQL 服务器提取错误信息。

从 MySQL 数据库后端来的错误不再发出警告,要用 <span class="function">mysql_error 来提取错误文本。注意本函数仅返回最近一次 MySQL 函数的执行(不包括 <span class="function">mysql_error 和 <span class="function">mysql_errno)的错误文本,因此如果要使用此函数,确保在调用另一个 MySQL 函数之前检查它的值。

示例 #1 mysql_error 例子

<?php
    mysql_connect("localhost", "mysql_user", "mysql_password");

    mysql_select_db("nonexistentdb");
    echo mysql_errno() . ": " . mysql_error(). "\n";

    mysql_select_db("kossu");
    mysql_query("SELECT * FROM nonexistenttable");
    echo mysql_errno() . ": " . mysql_error() . "\n";
?>

以上例子将产生如下输出:

1049: Unknown database 'nonexistentdb'
1146: Table 'kossu.nonexistenttable' doesn't exist

参见 mysql_errno

mysql_escape_string

转义一个字符串用于 mysql_query

说明

string <span class="methodname">mysql_escape_string ( <span class="methodparam">string $unescaped_string )

本函数将 unescaped_string 转义,使之可以安全用于 <span class="function">mysql_query。

Note: <span class="function">mysql_escape_string 并不转义 %_ 本函数和 <span class="function">mysql_real_escape_string 完全一样,除了 mysql_real_escape_string 接受的是一个连接句柄并根据当前字符集转移字符串之外。<span class="function">mysql_escape_string 并不接受连接参数,也不管当前字符集设定。

示例 #1 mysql_escape_string 例子

<?php
    $item = "Zak's Laptop";
    $escaped_item = mysql_escape_string($item);
    printf ("Escaped string: %s\n", $escaped_item);
?>

以上例子将产生如下输出:

Escaped string: Zak\'s Laptop

参见 mysql_real_escape_string,<span class="function">addslashes 和 magic_quotes_gpc 指令。

mysql_fetch_array

从结果集中取得一行作为关联数组

说明

array <span class="methodname">mysql_fetch_array ( <span class="methodparam">resource $result [, int $result_type ] )

mysql_fetch_array 是 <span class="function">mysql_fetch_row 的扩展版本。除了将数据以数字索引方式储存在数组中之外,还可以将数据作为关联索引储存,用字段名作为键名。

有一点很重要必须指出,用 <span class="function">mysql_fetch_array 并不明显 比用 <span class="function">mysql_fetch_row 慢,而且还提供了明显更多的值。

参数

result
resource 型的结果集。此结果集来自对 <span class="function">msql_query 的调用。

result_type
接受以下常量值: MSQL_ASSOCMSQL_NUMMSQL_BOTH,默认为 MSQL_BOTH。如果用了 MYSQL_BOTH,将得到一个同时包含关联和数字索引的数组。用 MYSQL_ASSOC 只得到关联索引(如同 mysql_fetch_assoc 那样),用 MYSQL_NUM 只得到数字索引(如同 <span class="function">mysql_fetch_row 那样)。

返回值

返回根据从结果集取得的行生成的数组,如果没有更多行则返回 false

范例

示例 #1 msql_fetch_array 示例

<?php
$con = msql_connect();
if (!$con) {
    die('Server connection problem: ' . msql_error());
}

if (!msql_select_db('test', $con)) {
    die('Database connection problem: ' . msql_error());
}

$result = msql_query('SELECT id, name FROM people', $con);
if (!$result) {
    die('Query execution problem: ' . msql_error());
}

while ($row = msql_fetch_array($result, MSQL_ASSOC)) {
    echo $row['id'] . ': ' . $row['name'] . "\n";
}

msql_free_result($result);
?>

参见

  • msql_fetch_row
  • msql_fetch_object
  • msql_data_seek
  • msql_result

mysql_fetch_assoc

从结果集中取得一行作为关联数组

Warning

本扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。应使用 MySQLiPDO_MySQL 扩展来替换之。参见 MySQL:选择 API 指南以及相关 FAQ 来获取更多信息。用以替代本函数的有:

  • mysqli_fetch_assoc
  • PDOStatement::fetch

说明

array <span class="methodname">mysql_fetch_assoc ( <span class="methodparam">resource $result )

返回对应结果集的关联数组,并且继续移动内部数据指针。 <span class="function">mysql_fetch_assoc 和用 <span class="function">mysql_fetch_array 加上第二个可选参数 MYSQL_ASSOC 完全相同。它仅仅返回关联数组。

参数

result
resource 型的结果集。此结果集来自对 <span class="function">mysql_query 的调用。

返回值

返回根据从结果集取得的行生成的关联数组;如果没有更多行则返回 false

如果结果中的两个或以上的列具有相同字段名,最后一列将优先。要访问同名的其它列,要么用 mysql_fetch_row 来取得数字索引或给该列起个别名。 参见 <span class="function">mysql_fetch_array 例子中有关别名说明。

范例

示例 #1 扩展的 mysql_fetch_assoc 例子

<?php

$conn = mysql_connect("localhost", "mysql_user", "mysql_password");

if (!$conn) {
    echo "Unable to connect to DB: " . mysql_error();
    exit;
}

if (!mysql_select_db("mydbname")) {
    echo "Unable to select mydbname: " . mysql_error();
    exit;
}

$sql = "SELECT id as userid, fullname, userstatus 
        FROM   sometable
        WHERE  userstatus = 1";

$result = mysql_query($sql);

if (!$result) {
    echo "Could not successfully run query ($sql) from DB: " . mysql_error();
    exit;
}

if (mysql_num_rows($result) == 0) {
    echo "No rows found, nothing to print so am exiting";
    exit;
}

// While a row of data exists, put that row in $row as an associative array
// Note: If you're expecting just one row, no need to use a loop
// Note: If you put extract($row); inside the following loop, you'll
//       then create $userid, $fullname, and $userstatus
while ($row = mysql_fetch_assoc($result)) {
    echo $row["userid"];
    echo $row["fullname"];
    echo $row["userstatus"];
}

mysql_free_result($result);

?>

注释

Note: 性能

必须指出一个要点: mysql_fetch_assocmysql_fetch_row不明显 慢,而且还提供了更多有用的值。

Note: <span class="simpara">此函数返回的字段名大小写敏感

Note: 此函数将 NULL 字段设置为 PHP null 值。

参见

  • mysql_fetch_row
  • mysql_fetch_array
  • mysql_data_seek
  • mysql_query
  • mysql_error

mysql_fetch_field

从结果集中取得列信息并作为对象返回

说明

object <span class="methodname">mysql_fetch_field ( <span class="methodparam">resource $result [, int $field_offset ] )

返回一个包含字段信息的对象。

mysql_fetch_field 可以用来从某个查询结果中取得字段的信息。如果没有指定字段偏移量,则下一个尚未被 mysql_fetch_field 取得的字段被提取。

对象的属性为:

  • name - 列名
  • table - 该列所在的表名
  • max_length - 该列最大长度
  • not_null - 1,如果该列不能为 null
  • primary_key - 1,如果该列是 primary key
  • unique_key - 1,如果该列是 unique key
  • multiple_key - 1,如果该列是 non-unique key
  • numeric - 1,如果该列是 numeric
  • blob - 1,如果该列是 BLOB
  • type - 该列的类型
  • unsigned - 1,如果该列是无符号数
  • zerofill - 1,如果该列是 zero-filled

Note: <span class="simpara">此函数返回的字段名大小写敏感

示例 #1 mysql_fetch_field

<?php
mysql_connect('localhost:3306', $user, $password)
    or die("Could not connect: " . mysql_error());
mysql_select_db("database");
$result = mysql_query("select * from table")
    or die("Query failed: " . mysql_error());
/* get column metadata */
$i = 0;
while ($i < mysql_num_fields($result)) {
    echo "Information for column $i:<br />\n";
    $meta = mysql_fetch_field($result);
    if (!$meta) {
        echo "No information available<br />\n";
    }
    echo "<pre>
blob:         $meta->blob
max_length:   $meta->max_length
multiple_key: $meta->multiple_key
name:         $meta->name
not_null:     $meta->not_null
numeric:      $meta->numeric
primary_key:  $meta->primary_key
table:        $meta->table
type:         $meta->type
unique_key:   $meta->unique_key
unsigned:     $meta->unsigned
zerofill:     $meta->zerofill
</pre>";
    $i++;
}
mysql_free_result($result);
?>

参见 mysql_field_seek

参数

result
resource 型的结果集。此结果集来自对 <span class="function">mysql_query 的调用。

field_offset
The numerical field offset. If the field offset is not specified, the next field that was not yet retrieved by this function is retrieved. The field_offset starts at 0.

返回值

Returns an object containing field information. The properties of the object are:

  • name - column name
  • table - name of the table the column belongs to
  • max_length - maximum length of the column
  • not_null - 1 if the column cannot be null
  • primary_key - 1 if the column is a primary key
  • unique_key - 1 if the column is a unique key
  • multiple_key - 1 if the column is a non-unique key
  • numeric - 1 if the column is numeric
  • blob - 1 if the column is a BLOB
  • type - the type of the column
  • unsigned - 1 if the column is unsigned
  • zerofill - 1 if the column is zero-filled

范例

示例 #2 mysql_fetch_field example

<?php
$conn = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$conn) {
    die('Could not connect: ' . mysql_error());
}
mysql_select_db('database');
$result = mysql_query('select * from table');
if (!$result) {
    die('Query failed: ' . mysql_error());
}
/* get column metadata */
$i = 0;
while ($i < mysql_num_fields($result)) {
    echo "Information for column $i:<br />\n";
    $meta = mysql_fetch_field($result, $i);
    if (!$meta) {
        echo "No information available<br />\n";
    }
    echo "<pre>
blob:         $meta->blob
max_length:   $meta->max_length
multiple_key: $meta->multiple_key
name:         $meta->name
not_null:     $meta->not_null
numeric:      $meta->numeric
primary_key:  $meta->primary_key
table:        $meta->table
type:         $meta->type
unique_key:   $meta->unique_key
unsigned:     $meta->unsigned
zerofill:     $meta->zerofill
</pre>";
    $i++;
}
mysql_free_result($result);
?>

注释

Note: <span class="simpara">此函数返回的字段名大小写敏感

参见

  • mysql_field_seek

mysql_fetch_lengths

取得结果集中每个输出的长度

说明

array <span class="methodname">mysql_fetch_lengths ( <span class="methodparam">resource $result )

以数组返回上一次用 mysql_fetch_row 取得的行中每个字段的长度,如果出错返回 false

mysql_fetch_lengths 将上一次 <span class="function">mysql_fetch_row,<span class="function">mysql_fetch_array 和 <span class="function">mysql_fetch_object 所返回的每个列的长度储存到一个数组中,偏移量从 0 开始。

参见 mysql_fetch_row

mysql_fetch_object

从结果集中取得一行作为对象返回

Warning

本扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。应使用 MySQLiPDO_MySQL 扩展来替换之。参见 MySQL:选择 API 指南以及相关 FAQ 来获取更多信息。用以替代本函数的有:

  • mysqli_fetch_object
  • PDOStatement::fetch

说明

object <span class="methodname">mysql_fetch_object ( <span class="methodparam">resource $result [, string $class_name [, <span class="type">array $params ]] )

返回一个对象,其属性与获取的行相对应,并将内部数据指针向前移动。

参数

result
resource 型的结果集。此结果集来自对 <span class="function">mysql_query 的调用。

class_name
要实例化、设置属性并返回的类的名称,如果不指定,默认返回 <span class="classname">stdClass 对象。

params
可选 array 数组参数,会传递给 class_name 类的构造函数。

返回值

返回根据所取得的行生成的对象 <span class="type">object,如果没有更多行则返回 false

范例

示例 #1 mysql_fetch_object example

<?php
mysql_connect("hostname", "user", "password");
mysql_select_db("mydb");
$result = mysql_query("select * from mytable");
while ($row = mysql_fetch_object($result)) {
    echo $row->user_id;
    echo $row->fullname;
}
mysql_free_result($result);
?>

示例 #2 mysql_fetch_object example

<?php
class foo {
    public $name;
}

mysql_connect("hostname", "user", "password");
mysql_select_db("mydb");

$result = mysql_query("select name from mytable limit 1");
$obj = mysql_fetch_object($result, 'foo');
var_dump($obj);
?>

注释

Note: Performance

速度上,本函数和 mysql_fetch_array 一样,也几乎和 mysql_fetch_row 一样快(差别很不明显)。

Note:

mysql_fetch_object 和 <span class="function">mysql_fetch_array 类似,只有一点区别 - 返回一个对象而不是数组。间接地也意味着只能通过字段名来访问数组,而不是偏移量(数字是合法的属性名)。

Note: <span class="simpara">此函数返回的字段名大小写敏感

Note: 此函数将 NULL 字段设置为 PHP null 值。

参见

  • mysql_fetch_array
  • mysql_fetch_assoc
  • mysql_fetch_row
  • mysql_data_seek
  • mysql_query

mysql_fetch_row

从结果集中取得一行作为枚举数组

说明

array <span class="methodname">mysql_fetch_row ( <span class="methodparam">resource $result )

返回根据所取得的行生成的数组,如果没有更多行则返回 false

mysql_fetch_row 从和指定的结果标识关联的结果集中取得一行数据并作为数组返回。每个结果的列储存在一个数组的单元中,偏移量从 0 开始。

依次调用 mysql_fetch_row 将返回结果集中的下一行,如果没有更多行则返回 false

参见 mysql_fetch_array,<span class="function">mysql_fetch_assoc,<span class="function">mysql_fetch_object,<span class="function">mysql_data_seek,<span class="function">mysql_fetch_lengths 和 <span class="function">mysql_result。

参数

result
resource 型的结果集。此结果集来自对 <span class="function">mysql_query 的调用。

返回值

Returns an numerical array of strings that corresponds to the fetched row, or false if there are no more rows.

mysql_fetch_row fetches one row of data from the result associated with the specified result identifier. The row is returned as an array. Each result column is stored in an array offset, starting at offset 0.

范例

示例 #1 Fetching one row with <span class="function">mysql_fetch_row

<?php
$result = mysql_query("SELECT id,email FROM people WHERE id = '42'");
if (!$result) {
    echo 'Could not run query: ' . mysql_error();
    exit;
}
$row = mysql_fetch_row($result);

echo $row[0]; // 42
echo $row[1]; // the email value
?>

注释

Note: 此函数将 NULL 字段设置为 PHP null 值。

参见

  • mysql_fetch_array
  • mysql_fetch_assoc
  • mysql_fetch_object
  • mysql_data_seek
  • mysql_fetch_lengths
  • mysql_result

mysql_field_flags

从结果中取得和指定字段关联的标志

说明

string <span class="methodname">mysql_field_flags ( <span class="methodparam">resource $result , int $field_offset )

mysql_field_flags 返回指定字段的字段标志。每个标志都用一个单词表示,之间用一个空格分开,因此可以用 explode 将其分开。

如果 MySQL 版本足够新,则会支持以下的标志:"not_null", "primary_key", "unique_key", "multiple_key", "blob", "unsigned", "zerofill", "binary", "enum", "auto_increment", "timestamp"。

为向下兼容仍然可以使用 <span class="function">mysql_fieldflags,但反对这样做。

mysql_field_len

返回指定字段的长度

说明

int <span class="methodname">mysql_field_len ( <span class="methodparam">resource $result , int $field_offset )

mysql_field_len 返回指定字段的长度。

为向下兼容仍然可以使用 <span class="function">mysql_fieldlen,但反对这样做。

mysql_field_name

取得结果中指定字段的字段名

说明

string <span class="methodname">mysql_field_name ( <span class="methodparam">resource $result , int $field_index )

mysql_field_name 返回指定字段索引的字段名。result 必须是一个合法的结果标识符,field_index 是该字段的数字偏移量。

Note:

field_index 从 0 开始。

例如,第三个字段的索引值其实是 2,第四个字段的索引值是 3,以此类推。

Note: <span class="simpara">此函数返回的字段名大小写敏感

示例 #1 mysql_field_name 例子

<?php
/* The users table consists of three fields:
 *   user_id
 *   username
 *   password.
 */
$link = mysql_connect('localhost', "mysql_user", "mysql_password");
$dbname = "mydb";
mysql_select_db($dbname, $link)
    or die("Could not set $dbname: " . mysql_error());
$res = mysql_query("select * from users", $link);

echo mysql_field_name($res, 0) . "\n";
echo mysql_field_name($res, 2);
?>

以上例子将产生如下输出:

user_id
password

为向下兼容仍然可以使用 <span class="function">mysql_fieldname,但反对这样做。

参数

result
resource 型的结果集。此结果集来自对 <span class="function">mysql_query 的调用。

field_offset
数值型字段偏移量。 field_offset0 开始。如果 field_offset 不存在,则会发出一个 E_WARNING 级别的错误

返回值

The name of the specified field index on success 或者在失败时返回 false.

范例

示例 #2 mysql_field_name example

<?php
/* The users table consists of three fields:
 *   user_id
 *   username
 *   password.
 */
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
    die('Could not connect to MySQL server: ' . mysql_error());
}
$dbname = 'mydb';
$db_selected = mysql_select_db($dbname, $link);
if (!$db_selected) {
    die("Could not set $dbname: " . mysql_error());
}
$res = mysql_query('select * from users', $link);

echo mysql_field_name($res, 0) . "\n";
echo mysql_field_name($res, 2);
?>

以上例程会输出:

user_id
password

注释

Note: <span class="simpara">此函数返回的字段名大小写敏感

Note:

为了向下兼容,可以使用下列已废弃的别名: <span class="function">mysql_fieldname

参见

  • mysql_field_type
  • mysql_field_len

mysql_field_seek

将结果集中的指针设定为制定的字段偏移量

说明

int <span class="methodname">mysql_field_seek ( <span class="methodparam">resource $result , int $field_offset )

用指定的字段偏移量检索。如果下一个 <span class="function">mysql_fetch_field 的调用不包括字段偏移量,则会返回本次 <span class="function">mysql_field_seek 中指定的偏移量的字段。

参见 mysql_fetch_field

mysql_field_table

取得指定字段所在的表名

说明

string <span class="methodname">mysql_field_table ( <span class="methodparam">resource $result , int $field_offset )

返回指定字段所在的表的名字。

为向下兼容仍然可以使用 <span class="function">mysql_fieldtable,但反对这样做。

mysql_field_type

取得结果集中指定字段的类型

说明

string <span class="methodname">mysql_field_type ( <span class="methodparam">resource $result , int $field_offset )

mysql_field_type 和 <span class="function">mysql_field_name 函数相似。参数完全相同,但返回的是字段类型而不是字段名。字段类型有“int”,“real”,“string”,“blob”以及其它,详见 » MySQL 手册

示例 #1 mysql_field_type 例子

<?php
    mysql_connect("localhost", "mysql_username", "mysql_password");
    mysql_select_db("mysql");
    $result = mysql_query("SELECT * FROM func");
    $fields = mysql_num_fields($result);
    $rows   = mysql_num_rows($result);
    $table = mysql_field_table($result, 0);
    echo "Your '".$table."' table has ".$fields." fields and ".$rows." record(s)\n";
    echo "The table has the following fields:\n";
    for ($i=0; $i < $fields; $i++) {
        $type  = mysql_field_type($result, $i);
        $name  = mysql_field_name($result, $i);
        $len   = mysql_field_len($result, $i);
        $flags = mysql_field_flags($result, $i);
        echo $type." ".$name." ".$len." ".$flags."\n";
    }
    mysql_free_result($result);
    mysql_close();
?>

以上例子将产生如下输出:

Your 'func' table has 4 fields and 1 record(s)
The table has the following fields:
string name 64 not_null primary_key binary
int ret 1 not_null
string dl 128 not_null
string type 9 not_null enum

为向下兼容仍然可以使用 <span class="function">mysql_fieldtype,但反对这样做。

参数

result
resource 型的结果集。此结果集来自对 <span class="function">mysql_query 的调用。

field_offset
数值型字段偏移量。 field_offset0 开始。如果 field_offset 不存在,则会发出一个 E_WARNING 级别的错误

返回值

The returned field type will be one of "int", "real", "string", "blob", and others as detailed in the » MySQL documentation.

范例

示例 #2 mysql_field_type example

<?php
mysql_connect("localhost", "mysql_username", "mysql_password");
mysql_select_db("mysql");
$result = mysql_query("SELECT * FROM func");
$fields = mysql_num_fields($result);
$rows   = mysql_num_rows($result);
$table  = mysql_field_table($result, 0);
echo "Your '" . $table . "' table has " . $fields . " fields and " . $rows . " record(s)\n";
echo "The table has the following fields:\n";
for ($i=0; $i < $fields; $i++) {
    $type  = mysql_field_type($result, $i);
    $name  = mysql_field_name($result, $i);
    $len   = mysql_field_len($result, $i);
    $flags = mysql_field_flags($result, $i);
    echo $type . " " . $name . " " . $len . " " . $flags . "\n";
}
mysql_free_result($result);
mysql_close();
?>

以上例程的输出类似于:

Your 'func' table has 4 fields and 1 record(s)
The table has the following fields:
string name 64 not_null primary_key binary
int ret 1 not_null
string dl 128 not_null
string type 9 not_null enum

注释

Note:

为了向下兼容,可以使用下列已废弃的别名: <span class="function">mysql_fieldtype

参见

  • mysql_field_name
  • mysql_field_len

mysql_free_result

释放结果内存

说明

bool <span class="methodname">mysql_free_result ( <span class="methodparam">resource $result )

mysql_free_result 将释放所有与结果标识符 result 所关联的内存。

mysql_free_result 仅需要在考虑到返回很大的结果集时会占用多少内存时调用。在脚本结束后所有关联的内存都会被自动释放。

成功时返回 true, 或者在失败时返回 false

为向下兼容仍然可以使用 <span class="function">mysql_freeresult,但反对这样做。

参数

result
resource 型的结果集。此结果集来自对 <span class="function">mysql_query 的调用。

返回值

成功时返回 true, 或者在失败时返回 false

If a non-resource is used for the result, an error of level E_WARNING will be emitted. It's worth noting that <span class="function">mysql_query only returns a <span class="type">resource for SELECT, SHOW, EXPLAIN, and DESCRIBE queries.

范例

示例 #1 A mysql_free_result example

<?php
$result = mysql_query("SELECT id,email FROM people WHERE id = '42'");
if (!$result) {
    echo 'Could not run query: ' . mysql_error();
    exit;
}
/* Use the result, assuming we're done with it afterwards */
$row = mysql_fetch_assoc($result);

/* Now we free up the result and continue on with our script */
mysql_free_result($result);

echo $row['id'];
echo $row['email'];
?>

注释

Note:

为了向下兼容,可以使用下列已废弃的别名: <span class="function">mysql_freeresult

参见

  • mysql_query
  • is_resource

mysql_get_client_info

取得 MySQL 客户端信息

说明

string <span class="methodname">mysql_get_client_info ( <span class="methodparam">void )

mysql_get_client_info 返回一个字符串指出了客户端库的版本。

示例 #1 mysql_get_client_info 例子

<?php
    printf ("MySQL client info: %s\n", mysql_get_client_info());
?>

以上例子将产生如下输出:

MySQL client info: 3.23.39

参见 mysql_get_host_info,<span class="function">mysql_get_proto_info 和 <span class="function">mysql_get_server_info。

mysql_get_host_info

取得 MySQL 主机信息

说明

string <span class="methodname">mysql_get_host_info ([ <span class="methodparam">resource $link_identifier ] )

mysql_get_host_info 返回一个字符串说明了连接 link_identifier 所使用的连接方式,包括服务器的主机名。如果省略 link_identifier,则使用上一个打开的连接。

示例 #1 mysql_get_host_info 例子

<?php
    mysql_connect("localhost", "mysql_user", "mysql_password") or
        die("Could not connect: " . mysql_error());
    printf ("MySQL host info: %s\n", mysql_get_host_info());
?>

以上例子将产生如下输出:

MySQL host info: Localhost via UNIX socket

参见 mysql_get_client_info,<span class="function">mysql_get_proto_info 和 <span class="function">mysql_get_server_info。

mysql_get_proto_info

取得 MySQL 协议信息

说明

int <span class="methodname">mysql_get_proto_info ([ <span class="methodparam">resource $link_identifier ] )

mysql_get_proto_info 返回 link_identifier 所使用的协议版本。如果省略 link_identifier,则使用上一个打开的连接。

示例 #1 mysql_get_proto_info 例子

<?php
    mysql_connect("localhost", "mysql_user", "mysql_password") or
        die("Could not connect: " . mysql_error());
    printf ("MySQL protocol version: %s\n", mysql_get_proto_info());
?>

以上例子将产生如下输出:

MySQL protocol version: 10

参见 mysql_get_client_info,<span class="function">mysql_get_host_info 和 <span class="function">mysql_get_server_info。

mysql_get_server_info

取得 MySQL 服务器信息

说明

string <span class="methodname">mysql_get_server_info ([ <span class="methodparam">resource $link_identifier ] )

mysql_get_server_info 返回 link_identifier 所使用的服务器版本。如果省略 link_identifier,则使用上一个打开的连接。

示例 #1 mysql_get_server_info 例子

<?php
    mysql_connect("localhost", "mysql_user", "mysql_password") or
        die("Could not connect: " . mysql_error());
    printf ("MySQL server version: %s\n", mysql_get_server_info());
?>

以上例子将产生如下输出:

MySQL server version: 4.0.1-alpha

参见 mysql_get_client_info,<span class="function">mysql_get_host_info 和 <span class="function">mysql_get_proto_info。

mysql_info

取得最近一条查询的信息

说明

string <span class="methodname">mysql_info ([ <span class="methodparam">resource $link_identifier ] )

mysql_info 返回通过给定的 link_identifier 所进行的最新一条查询的详细信息。如果没有指定 link_identifier,则假定为上一个打开的连接。

mysql_info 对以下列出的所有语句返回一个字符串。对于其它任何语句返回 false。字符串的格式取决于给出的语句。

示例 #1 相关的 MySQL 语句

INSERT INTO ... SELECT ...
字符串格式:Records: 23 Duplicates: 0 Warnings: 0
INSERT INTO ... VALUES (...),(...),(...)...
字符串格式:Records: 37 Duplicates: 0 Warnings: 0
LOAD DATA INFILE ...
字符串格式:Records: 42 Deleted: 0 Skipped: 0 Warnings: 0
ALTER TABLE
字符串格式:Records: 60 Duplicates: 0 Warnings: 0
UPDATE
字符串格式:Rows matched: 65 Changed: 65 Warnings: 0

上例中的数字只是为了演示的目的,实际的值取决于查询。

Note:

mysql_info 对于 INSERT ... VALUES 语句仅在该语句中列出了多个值的情况下返回一个非 false 的值。

参见 mysql_affected_rows

mysql_insert_id

取得上一步 INSERT 操作产生的 ID

说明

int <span class="methodname">mysql_insert_id ([ <span class="methodparam">resource $link_identifier ] )

mysql_insert_id 返回给定的 link_identifier 中上一步 INSERT 查询中产生的 AUTO_INCREMENT 的 ID 号。如果没有指定 link_identifier,则使用上一个打开的连接。

如果上一查询没有产生 AUTO_INCREMENT 的值,则 <span class="function">mysql_insert_id 返回 0。如果需要保存该值以后使用,要确保在产生了值的查询之后立即调用 <span class="function">mysql_insert_id。

Note:

MySQL 中的 SQL 函数 LAST_INSERT_ID() 总是保存着最新产生的 AUTO_INCREMENT 值,并且不会在查询语句之间被重置。

Warning

mysql_insert_id 将 MySQL 内部的 C API 函数 mysql_insert_id() 的返回值转换成 long(PHP 中命名为 <span class="type">int)。如果 AUTO_INCREMENT 的列的类型是 BIGINT,则 mysql_insert_id 返回的值将不正确。可以在 SQL 查询中用 MySQL 内部的 SQL 函数 LAST_INSERT_ID() 来替代。

示例 #1 mysql_insert_id 例子

<?php
    mysql_connect("localhost", "mysql_user", "mysql_password") or
        die("Could not connect: " . mysql_error());
    mysql_select_db("mydb");

    mysql_query("INSERT INTO mytable (product) values ('kossu')");
    printf ("Last inserted record has id %d\n", mysql_insert_id());
?>

参见 mysql_query

mysql_list_dbs

列出 MySQL 服务器中所有的数据库

说明

resource <span class="methodname">mysql_list_dbs ([ <span class="methodparam">resource $link_identifier ] )

mysql_list_dbs 将返回一个结果指针,包含了当前 MySQL 进程中所有可用的数据库。用 <span class="function">mysql_tablename 函数来遍历此结果指针,或者任何使用结果表的函数,例如 <span class="function">mysql_fetch_array。

示例 #1 mysql_list_dbs 例子

<?php
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
$db_list = mysql_list_dbs($link);

while ($row = mysql_fetch_object($db_list)) {
    echo $row->Database . "\n";
}
?>

以上例子将产生如下输出:

database1
database2
database3
...

Note:

以上代码用起来和 mysql_fetch_row 或类似函数一样简单。

为向下兼容仍然可以使用 <span class="function">mysql_listdbs,但反对这样做。

参见 mysql_db_name

mysql_list_fields

列出 MySQL 结果中的字段

说明

resource <span class="methodname">mysql_list_fields ( <span class="methodparam">string $database_name , <span class="type">string $table_name [, <span class="methodparam">resource $link_identifier ] )

mysql_list_fields 取得给定表名的信息。参数是数据库名和表名。返回一个结果指针,可以用于 mysql_field_flags,<span class="function">mysql_field_len,<span class="function">mysql_field_name 和 <span class="function">mysql_field_type。

示例 #1 mysql_list_fields 例子

<?php
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');

$fields = mysql_list_fields("database1", "table1", $link);
$columns = mysql_num_fields($fields);

for ($i = 0; $i < $columns; $i++) {
    echo mysql_field_name($fields, $i) . "\n";
}

以上例子将产生如下输出:

field1
field2
field3
...

为向下兼容仍然可以使用 <span class="function">mysql_listfields,但反对这样做。

Note:

mysql_list_fields 函数已过时。最好用 mysql_query 来发出一条 SHOW COLUMNS FROM table [LIKE 'name'] 的 SQL 语句来代替。

mysql_list_processes

列出 MySQL 进程

说明

resource <span class="methodname">mysql_list_processes ([ <span class="methodparam">resource $link_identifier ] )

mysql_list_processes 返回一个结果指针,说明了当前服务器的线程。

示例 #1 mysql_list_processes 例子

<?php
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');

$result = mysql_list_processes($link);
while ($row = mysql_fetch_assoc($result)){
    printf("%s %s %s %s %s\n", $row["Id"], $row["Host"], $row["db"],
       $row["Command"], $row["Time"]);
}
mysql_free_result ($result);
?>

以上例子将产生如下输出:

1 localhost test Processlist 0
4 localhost mysql sleep 5

参见 mysql_thread_id

mysql_list_tables

列出 MySQL 数据库中的表

说明

resource <span class="methodname">mysql_list_tables ( <span class="methodparam">string $database [, resource $link_identifier ] )

mysql_list_tables 接受一个数据库名并返回和 mysql_query 函数很相似的一个结果指针。用 <span class="function">mysql_tablename 函数来遍历此结果指针,或者任何使用结果表的函数,例如 <span class="function">mysql_fetch_array。

database 参数是需要被取得其中的的表名的数据库名。如果失败 <span class="function">mysql_list_tables 返回 false

为向下兼容仍然可以使用本函数的别名 <span class="function">mysql_listtables,但反对这样做。

Note: 该函数已经被删除了,请不要再使用该函数。您可以用命令 SHOW TABLES FROM DATABASE 来实现该函数的功能。

示例 #1 mysql_list_tables 例子

<?php
    $dbname = 'mysql_dbname';

    if (!mysql_connect('mysql_host', 'mysql_user', 'mysql_password')) {
        print 'Could not connect to mysql';
        exit;
    }

    $result = mysql_list_tables($dbname);

    if (!$result) {
        print "DB Error, could not list tables\n";
        print 'MySQL Error: ' . mysql_error();
        exit;
    }

    while ($row = mysql_fetch_row($result)) {
        print "Table: $row[0]\n";
    }

    mysql_free_result($result);
?>

参见 mysql_list_dbs 和 <span class="function">mysql_tablename。

mysql_num_fields

取得结果集中字段的数目

说明

int <span class="methodname">mysql_num_fields ( <span class="methodparam">resource $result )

mysql_num_fields 返回结果集中字段的数目。

参见 mysql_select_db,<span class="function">mysql_query,<span class="function">mysql_fetch_field 和 <span class="function">mysql_num_rows。

为向下兼容仍然可以使用 <span class="function">mysql_numfields,但反对这样做。

mysql_num_rows

取得结果集中行的数目

说明

int <span class="methodname">mysql_num_rows ( <span class="methodparam">resource $result )

mysql_num_rows 返回结果集中行的数目。此命令仅对 SELECT 语句有效。要取得被 INSERT,UPDATE 或者 DELETE 查询所影响到的行的数目,用 <span class="function">mysql_affected_rows。

示例 #1 mysql_num_rows 例子

<?php

$link = mysql_connect("localhost", "mysql_user", "mysql_password");
mysql_select_db("database", $link);

$result = mysql_query("SELECT * FROM table1", $link);
$num_rows = mysql_num_rows($result);

echo "$num_rows Rows\n";

?>

Note:

如果使用 <span class="function">mysql_unbuffered_query,则直到结果集中的所有行都被提取后 mysql_num_rows 才能返回正确的值。

参见 mysql_affected_rows,<span class="function">mysql_connect,<span class="function">mysql_data_seek,<span class="function">mysql_select_db 和 <span class="function">mysql_query。

为向下兼容仍然可以使用 <span class="function">mysql_numrows,但反对这样做。

mysql_pconnect

打开一个到 MySQL 服务器的持久连接

说明

resource <span class="methodname">mysql_pconnect ([ <span class="methodparam">string $server [, string $username [, <span class="type">string $password [, <span class="methodparam">int $client_flags ]]]] )

如果成功则返回一个正的 MySQL 持久连接标识符,出错则返回 false

mysql_pconnect 建立一个到 MySQL 服务器的连接。如果没有提供可选参数,则使用如下默认值:server = 'localhost:3306',username = 服务器进程所有者的用户名,password = 空密码。client_flags 参数可以是以下常量的组合:MYSQL_CLIENT_COMPRESS,MYSQL_CLIENT_IGNORE_SPACE 或者 MYSQL_CLIENT_INTERACTIVE。

server 参数也可以包括端口号,例如 "hostname:port",或者是本机套接字的的路径,例如 ":/path/to/socket"。

Note:

对 ":port" 的支持是 3.0B4 版添加的。

对 ":/path/to/socket" 的支持是 3.0.10 版添加的。

mysql_pconnect 和 <span class="function">mysql_connect 非常相似,但有两个主要区别。

首先,当连接的时候本函数将先尝试寻找一个在同一个主机上用同样的用户名和密码已经打开的(持久)连接,如果找到,则返回此连接标识而不打开新连接。

其次,当脚本执行完毕后到 SQL 服务器的连接不会被关闭,此连接将保持打开以备以后使用(<span class="function">mysql_close 不会关闭由 <span class="function">mysql_pconnect 建立的连接)。

可选参数 client_flags 自 PHP 4.3.0 版起可用。

此种连接称为“持久的”。

Note:

注意,此种连接仅能用于模块版本的 PHP。更多信息参见数据库持久连接一节。

Warning

使用持久连接需要调整一些 Apache 和 MySQL 的配置以使不会超出 MySQL 所允许的连接数目。

mysql_ping

Ping 一个服务器连接,如果没有连接则重新连接

说明

bool <span class="methodname">mysql_ping ([ <span class="methodparam">resource $ link_identifier ] )

mysql_ping 检查到服务器的连接是否正常。如果断开,则自动尝试连接。本函数可用于空闲很久的脚本来检查服务器是否关闭了连接,如果有必要则重新连接上。如果到服务器的连接可用则 mysql_ping 返回 true,否则返回 false

参见 mysql_thread_id 和 <span class="function">mysql_list_processes。

mysql_query

发送一条 MySQL 查询

Warning

本扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。应使用 MySQLiPDO_MySQL 扩展来替换之。参见 MySQL:选择 API 指南以及相关 FAQ 来获取更多信息。用以替代本函数的有:

  • mysqli_query
  • PDO::query

说明

resource <span class="methodname">mysql_query ( <span class="type">string $query [, <span class="methodparam">resource $link_identifier = NULL ] )

mysql_query 向与指定的 link_identifier 关联的服务器中的当前活动数据库发送一条查询(不支持多条查询)。

参数

query
SQL 查询语句

查询字符串不应以分号结束。 查询中被嵌入的数据应该正确地转义

link_identifier
MySQL 连接。如不指定连接标识,则使用由 <span class="function">mysql_connect 最近打开的连接。如果没有找到该连接,会尝试不带参数调用 <span class="function">mysql_connect 来创建。如没有找到连接或无法建立连接,则会生成 E_WARNING 级别的错误。

返回值

mysql_query 仅对 SELECT,SHOW,DESCRIBE, EXPLAIN 和其他语句 语句返回一个 <span class="type">resource,如果查询出现错误则返回 false

对于其它类型的 SQL 语句,比如INSERT, UPDATE, DELETE, DROP 之类, <span class="function">mysql_query 在执行成功时返回 true,出错时返回 false

返回的结果资源应该传递给 <span class="function">mysql_fetch_array 和其他函数来处理结果表,取出返回的数据。

假定查询成功,可以调用 mysql_num_rows 来查看对应于 SELECT 语句返回了多少行,或者调用 <span class="function">mysql_affected_rows 来查看对应于 DELETE,INSERT,REPLACE 或 UPDATE 语句影响到了多少行。

如果没有权限访问查询语句中引用的表时,<span class="function">mysql_query 也会返回 false

范例

示例 #1 无效的查询

以下查询语法上有错,因此 mysql_query 失败并返回 false

<?php
$result = mysql_query('SELECT * WHERE 1=1');
if (!$result) {
    die('Invalid query: ' . mysql_error());
}

?>

示例 #2 有效的查询

以下查询语法正确,所以 mysql_query 返回了一个 resource

<?php
// 这应该由用户提供,下面是一个示例
$firstname = 'fred';
$lastname  = 'fox';

// 构造查询
// 这是执行 SQL 最好的方式
// 更多例子参见 mysql_real_escape_string()
$query = sprintf("SELECT firstname, lastname, address, age FROM friends 
    WHERE firstname='%s' AND lastname='%s'",
    mysql_real_escape_string($firstname),
    mysql_real_escape_string($lastname));

// 执行查询
$result = mysql_query($query);

// 检查结果
// 下面显示了实际发送给 MySQL 的查询,以及出现的错误。这对调试很有帮助。
if (!$result) {
    $message  = 'Invalid query: ' . mysql_error() . "\n";
    $message .= 'Whole query: ' . $query;
    die($message);
}

// 结果的使用
// 尝试 print $result 并不会取出结果资源中的信息
// 所以必须至少使用其中一个 mysql 结果函数
// 参见 mysql_result(), mysql_fetch_array(), mysql_fetch_row() 等。
while ($row = mysql_fetch_assoc($result)) {
    echo $row['firstname'];
    echo $row['lastname'];
    echo $row['address'];
    echo $row['age'];
}

// 释放关联结果集的资源
// 在脚本结束的时候会自动进行
mysql_free_result($result);
?>

参见

  • mysql_connect
  • mysql_error
  • mysql_real_escape_string
  • mysql_result
  • mysql_fetch_assoc
  • mysql_unbuffered_query

mysql_real_escape_string

转义 SQL 语句中使用的字符串中的特殊字符,并考虑到连接的当前字符集

Warning

本扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。应使用 MySQLiPDO_MySQL 扩展来替换之。参见 MySQL:选择 API 指南以及相关 FAQ 来获取更多信息。用以替代本函数的有:

  • mysqli_real_escape_string
  • PDO::quote

说明

string <span class="methodname">mysql_real_escape_string ( <span class="methodparam">string $unescaped_string [, <span class="type">resource $link_identifier<span class="initializer"> = NULL ] )

本函数将 unescaped_string 中的特殊字符转义,并计及连接的当前字符集,因此可以安全用于 <span class="function">mysql_query。

mysql_real_escape_string 调用mysql库的函数 mysql_real_escape_string, 在以下字符前添加反斜杠: \x00, \n, \r, \*, ', "\x1a*.

为了安全起见,在像MySQL传送查询前,必须调用这个函数(除了少数例外情况)。

Caution

The character set must be set either at the server level, or with the API function mysql_set_charset for it to affect mysql_real_escape_string. See the concepts section on character sets for more information.

参数

unescaped_string
The string that is to be escaped.

link_identifier
MySQL 连接。如不指定连接标识,则使用由 <span class="function">mysql_connect 最近打开的连接。如果没有找到该连接,会尝试不带参数调用 <span class="function">mysql_connect 来创建。如没有找到连接或无法建立连接,则会生成 E_WARNING 级别的错误。

返回值

Returns the escaped string, or false on error.

错误/异常

Executing this function without a MySQL connection present will also emit E_WARNING level PHP errors. Only execute this function with a valid MySQL connection present.

范例

示例 #1 mysql_real_escape_string 例子

<?php
// Connect
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
    OR die(mysql_error());

// Query
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
            mysql_real_escape_string($user),
            mysql_real_escape_string($password));
?>

示例 #2 mysql_real_escape_string requires a connection example

This example demonstrates what happens if a MySQL connection is not present when calling this function.

<?php
// We have not connected to MySQL

$lastname  = "O'Reilly";
$_lastname = mysql_real_escape_string($lastname);

$query = "SELECT * FROM actors WHERE last_name = '$_lastname'";

var_dump($_lastname);
var_dump($query);
?>

以上例程的输出类似于:

Warning: mysql_real_escape_string(): No such file or directory in /this/test/script.php on line 5
Warning: mysql_real_escape_string(): A link to the server could not be established in /this/test/script.php on line 5

bool(false)
string(41) "SELECT * FROM actors WHERE last_name = ''"

示例 #3 An example SQL Injection Attack

<?php
// We didn't check $_POST['password'], it could be anything the user wanted! For example:
$_POST['username'] = 'aidan';
$_POST['password'] = "' OR ''='";

// Query database to check if there are any matching users
$query = "SELECT * FROM users WHERE user='{$_POST['username']}' AND password='{$_POST['password']}'";
mysql_query($query);

// This means the query sent to MySQL would be:
echo $query;
?>

The query sent to MySQL:

SELECT * FROM users WHERE user='aidan' AND password='' OR ''=''

This would allow anyone to log in without a valid password.

注释

Note:

A MySQL connection is required before using <span class="function">mysql_real_escape_string otherwise an error of level E_WARNING is generated, and false is returned. If link_identifier isn't defined, the last MySQL connection is used.

Note:

If magic_quotes_gpc is enabled, first apply stripslashes to the data. Using this function on data which has already been escaped will escape the data twice.

Note:

If this function is not used to escape data, the query is vulnerable to SQL Injection Attacks.

Note: <span class="function">mysql_real_escape_string does not escape % and _. These are wildcards in MySQL if combined with LIKE, GRANT, or REVOKE.

参见

mysql_result

取得结果数据

说明

mixed <span class="methodname">mysql_result ( <span class="methodparam">resource $result , int $row [, mixed $field ] )

mysql_result 返回 MySQL 结果集中一个单元的内容。字段参数可以是字段的偏移量或者字段名,或者是字段表点字段名(tablename.fieldname)。如果给列起了别名('select foo as bar from...'),则用别名替代列名。

当作用于很大的结果集时,应该考虑使用能够取得整行的函数(在下边指出)。这些函数在一次函数调用中返回了多个单元的内容,比 mysql_result 快得多。此外注意在字段参数中指定数字偏移量比指定字段名或者 tablename.fieldname 要快得多。

调用 mysql_result 不能和其它处理结果集的函数混合调用。

示例 #1 mysql_result 例子

<?php
    $link = mysql_connect("localhost", "mysql_user", "mysql_password")
            or die("Could not connect: " . mysql_error());

    $result = mysql_query("SELECT name FROM work.employee")
            or die("Could not query: . mysql_error());

    echo mysql_result($result,2); // outputs third employee's name

    mysql_close($link);
?>

推荐使用高性能的替代函数:<span class="function">mysql_fetch_row,<span class="function">mysql_fetch_array,<span class="function">mysql_fetch_assoc 和 <span class="function">mysql_fetch_object。

mysql_select_db

选择 MySQL 数据库

说明

bool <span class="methodname">mysql_select_db ( <span class="methodparam">string $database_name [, <span class="type">resource $ link_identifier ] )

成功时返回 true, 或者在失败时返回 false

mysql_select_db 设定与指定的连接标识符所关联的服务器上的当前激活数据库。如果没有指定连接标识符,则使用上一个打开的连接。如果没有打开的连接,本函数将无参数调用 mysql_connect 来尝试打开一个并使用之。

每个其后的 mysql_query 调用都会作用于活动数据库。

示例 #1 mysql_select_db 例子

<?php

$lnk = mysql_connect('localhost', 'mysql_user', 'mysql_password')
       or die ('Not connected : ' . mysql_error());

// make foo the current db
mysql_select_db('foo', $lnk) or die ('Can\'t use foo : ' . mysql_error());

?>

参见 mysql_connect,<span class="function">mysql_pconnect 和 <span class="function">mysql_query。

为向下兼容仍然可以使用 <span class="function">mysql_selectdb,但反对这样做。

参数

database_name
The name of the database that is to be selected.

link_identifier
MySQL 连接。如不指定连接标识,则使用由 <span class="function">mysql_connect 最近打开的连接。如果没有找到该连接,会尝试不带参数调用 <span class="function">mysql_connect 来创建。如没有找到连接或无法建立连接,则会生成 E_WARNING 级别的错误。

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #2 mysql_select_db example

<?php

$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
    die('Not connected : ' . mysql_error());
}

// make foo the current db
$db_selected = mysql_select_db('foo', $link);
if (!$db_selected) {
    die ('Can\'t use foo : ' . mysql_error());
}
?>

注释

Note:

为了向下兼容,可以使用下列已废弃的别名: <span class="function">mysql_selectdb

参见

  • mysql_connect
  • mysql_pconnect
  • mysql_query

mysql_set_charset

设置客户端的字符集

Note:

本扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。应使用 MySQLiPDO_MySQL 扩展来替换之。参见 MySQL:选择 API 指南以及相关 FAQ 来获取更多信息。用以替代本函数的有:

  • mysqli_character_set_name
  • PDO: 添加 charset 到连接字符串,比如 charset=utf8

说明

bool <span class="methodname">mysql_set_charset ( <span class="methodparam">string $charset [, resource $link_identifier = NULL ] )

设置当前连接的默认字符集。

参数

charset
一个有效的字符集名称。

link_identifier
MySQL 连接。如不指定连接标识,则使用由 <span class="function">mysql_connect 最近打开的连接。如果没有找到该连接,会尝试不带参数调用 <span class="function">mysql_connect 来创建。如没有找到连接或无法建立连接,则会生成 E_WARNING 级别的错误。

返回值

成功时返回 true, 或者在失败时返回 false

注释

Note:

本函数需要 MySQL 5.0.7 或更高版本。

Note:

这是改变字符集的最佳方式。不推荐您使用 <span class="function">mysql_query 来设置 (比如 SET NAMES utf8)。 更多信息参见 MySQL character set concepts 一节。

参见

mysql_stat

取得当前系统状态

说明

string <span class="methodname">mysql_stat ([ <span class="methodparam">resource $link_identifier ] )

mysql_stat 返回当前服务器状态。

Note:

mysql_stat 目前只返回 uptime,threads,queries,open tables,flush tables 和 queries per second。要得到其它状态变量的完整列表,只能使用 SQL 命令 SHOW STATUS。

示例 #1 mysql_stat 例子

<?php
$link = mysql_connect('localhost', "mysql_user", "mysql_password");
$status = explode('  ', mysql_stat($link));
print_r($status);
?>

以上例子将产生如下输出:

Array
(
    [0] => Uptime: 5380
    [1] => Threads: 2
    [2] => Questions: 1321299
    [3] => Slow queries: 0
    [4] => Opens: 26
    [5] => Flush tables: 1
    [6] => Open tables: 17
    [7] => Queries per second avg: 245.595
)

mysql_tablename

取得表名

说明

string <span class="methodname">mysql_tablename ( <span class="methodparam">resource $result , int $i )

mysql_tablename 接受 <span class="function">mysql_list_tables 返回的结果指针以及一个整数索引作为参数并返回表名。可以用 <span class="function">mysql_num_rows 函数来判断结果指针中的表的数目。用 <span class="function">mysql_tablename 函数来遍历此结果指针,或者任何处理结果表的函数,例如 <span class="function">mysql_fetch_array。

示例 #1 mysql_tablename 例子

<?php
    mysql_connect("localhost", "mysql_user", "mysql_password");
    $result = mysql_list_tables("mydb");

    for ($i = 0; $i < mysql_num_rows($result); $i++)
        printf ("Table: %s\n", mysql_tablename($result, $i));

    mysql_free_result($result);
?>

参见 mysql_list_tables

mysql_thread_id

返回当前线程的 ID

说明

int <span class="methodname">mysql_thread_id ([ <span class="methodparam">resource $link_identifier ] )

mysql_thread_id 返回当前线程的 ID。如果连接丢失了并用 mysql_ping 重新连接上,线程 ID 会改变。这意味着不能取得线程的 ID 后保存起来备用。当需要的时候再去获取之。

示例 #1 mysql_thread_id 例子

<?php
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
$thread_id = mysql_thread_id($link);
if ($thread_id){
    printf ("current thread id is %d\n", $thread_id);
}
?>

以上例子将产生如下输出:

current thread id is 73

参见 mysql_ping 和 <span class="function">mysql_list_processes。

mysql_unbuffered_query

向 MySQL 发送一条 SQL 查询,并不获取和缓存结果的行

说明

resource <span class="methodname">mysql_unbuffered_query ( <span class="methodparam">string $query [, resource $link_identifier ] )

mysql_unbuffered_query 向 MySQL 发送一条 SQL 查询 query,但不像 mysql_query 那样自动获取并缓存结果集。一方面,这在处理很大的结果集时会节省可观的内存。另一方面,可以在获取第一行后立即对结果集进行操作,而不用等到整个 SQL 语句都执行完毕。当使用多个数据库连接时,必须指定可选参数 link_identifier

Note:

mysql_unbuffered_query 的好处是有代价的:在 <span class="function">mysql_unbuffered_query 返回的结果集之上不能使用 <span class="function">mysql_num_rows 和 <span class="function">mysql_data_seek。此外在向 MySQL 发送一条新的 SQL 查询之前,必须提取掉所有未缓存的 SQL 查询所产生的结果行。

参见 mysql_query

目录

MySQL Native Driver

目录

MySQL Native Driver is a replacement for the MySQL Client Library (libmysqlclient). MySQL Native Driver is part of the official PHP sources as of PHP 5.3.0.

The MySQL database extensions MySQL extension, mysqli and PDO MYSQL all communicate with the MySQL server. In the past, this was done by the extension using the services provided by the MySQL Client Library. The extensions were compiled against the MySQL Client Library in order to use its client-server protocol.

With MySQL Native Driver there is now an alternative, as the MySQL database extensions can be compiled to use MySQL Native Driver instead of the MySQL Client Library.

MySQL Native Driver is written in C as a PHP extension.

Overview

What it is not

Although MySQL Native Driver is written as a PHP extension, it is important to note that it does not provide a new API to the PHP programmer. The programmer APIs for MySQL database connectivity are provided by the MySQL extension, mysqli and PDO MYSQL. These extensions can now use the services of MySQL Native Driver to communicate with the MySQL Server. Therefore, you should not think of MySQL Native Driver as an API.

Why use it?

Using the MySQL Native Driver offers a number of advantages over using the MySQL Client Library.

The older MySQL Client Library was written by MySQL AB (now Oracle Corporation) and so was released under the MySQL license. This ultimately led to MySQL support being disabled by default in PHP. However, the MySQL Native Driver has been developed as part of the PHP project, and is therefore released under the PHP license. This removes licensing issues that have been problematic in the past.

Also, in the past, you needed to build the MySQL database extensions against a copy of the MySQL Client Library. This typically meant you needed to have MySQL installed on a machine where you were building the PHP source code. Also, when your PHP application was running, the MySQL database extensions would call down to the MySQL Client library file at run time, so the file needed to be installed on your system. With MySQL Native Driver that is no longer the case as it is included as part of the standard distribution. So you do not need MySQL installed in order to build PHP or run PHP database applications.

Because MySQL Native Driver is written as a PHP extension, it is tightly coupled to the workings of PHP. This leads to gains in efficiency, especially when it comes to memory usage, as the driver uses the PHP memory management system. It also supports the PHP memory limit. Using MySQL Native Driver leads to comparable or better performance than using MySQL Client Library, it always ensures the most efficient use of memory. One example of the memory efficiency is the fact that when using the MySQL Client Library, each row is stored in memory twice, whereas with the MySQL Native Driver each row is only stored once in memory.

Note: Reporting memory usage

Because MySQL Native Driver uses the PHP memory management system, its memory usage can be tracked with <span class="function">memory_get_usage. This is not possible with libmysqlclient because it uses the C function malloc() instead.

Special features

MySQL Native Driver also provides some special features not available when the MySQL database extensions use MySQL Client Library. These special features are listed below:

  • Improved persistent connections

  • The special function <span class="function">mysqli_fetch_all

  • Performance statistics calls: <span class="function">mysqli_get_client_stats, <span class="function">mysqli_get_connection_stats

The performance statistics facility can prove to be very useful in identifying performance bottlenecks.

MySQL Native Driver also allows for persistent connections when used with the mysqli extension.

SSL Support

MySQL Native Driver has supported SSL since PHP version 5.3.3

Compressed Protocol Support

As of PHP 5.3.2 MySQL Native Driver supports the compressed client server protocol. MySQL Native Driver did not support this in 5.3.0 and 5.3.1. Extensions such as ext/mysql, ext/mysqli, that are configured to use MySQL Native Driver, can also take advantage of this feature. Note that PDO_MYSQL does NOT support compression when used together with mysqlnd.

Named Pipes Support

Named pipes support for Windows was added in PHP version 5.4.0.

Installation

更新日志

版本 说明
5.3.0 The MySQL Native Driver was added, with support for all MySQL extensions (i.e., mysql, mysqli and PDO_MYSQL). Passing in mysqlnd to the appropriate configure switch enables this support.
5.4.0 The MySQL Native Driver is now the default for all MySQL extensions (i.e., mysql, mysqli and PDO_MYSQL). Passing in mysqlnd to configure is now optional.
5.5.0 SHA-256 Authentication Plugin support was added

Installation on Unix

The MySQL database extensions must be configured to use the MySQL Client Library. In order to use the MySQL Native Driver, PHP needs to be built specifying that the MySQL database extensions are compiled with MySQL Native Driver support. This is done through configuration options prior to building the PHP source code.

For example, to build the MySQL extension, mysqli and PDO MYSQL using the MySQL Native Driver, the following command would be given:

./configure --with-mysql=mysqlnd \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
[other options]

Installation on Windows

In the official PHP Windows distributions from 5.3 onwards, MySQL Native Driver is enabled by default, so no additional configuration is required to use it. All MySQL database extensions will use MySQL Native Driver in this case.

SHA-256 Authentication Plugin support

The MySQL Native Driver requires the OpenSSL functionality of PHP to be loaded and enabled to connect to MySQL through accounts that use the MySQL SHA-256 Authentication Plugin. For example, PHP could be configured using:

./configure --with-mysql=mysqlnd \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
--with-openssl
[other options]

运行时配置

这些函数的行为受 php.ini 中的设置影响。

名字 默认 可修改范围 更新日志
mysqlnd.collect_statistics "1" PHP_INI_SYSTEM Available since PHP 5.3.0.
mysqlnd.collect_memory_statistics "0" PHP_INI_SYSTEM Available since PHP 5.3.0.
mysqlnd.debug "" PHP_INI_SYSTEM Available since PHP 5.3.0.
mysqlnd.log_mask 0 PHP_INI_ALL Available since PHP 5.3.0
mysqlnd.mempool_default_size 16000 PHP_INI_ALL Available since PHP 5.3.3
mysqlnd.net_read_timeout "86400" PHP_INI_ALL Available since PHP 5.3.0. Before PHP 7.2.0 the default value was "31536000" and the changeability was PHP_INI_SYSTEM
mysqlnd.net_cmd_buffer_size 5.3.0 - "2048", 5.3.1 - "4096" PHP_INI_SYSTEM Available since PHP 5.3.0.
mysqlnd.net_read_buffer_size "32768" PHP_INI_SYSTEM Available since PHP 5.3.0.
mysqlnd.sha256_server_public_key "" PHP_INI_PERDIR Available since PHP 5.5.0.
mysqlnd.trace_alloc "" PHP_INI_SYSTEM Available since PHP 5.5.0.
mysqlnd.fetch_data_copy 0 PHP_INI_ALL Available since PHP 5.6.0.

有关 PHP_INI_* 样式的更多详情与定义,见 配置可被设定范围

这是配置指令的简短说明。

mysqlnd.collect_statistics bool
Enables the collection of various client statistics which can be accessed through <span class="function">mysqli_get_client_stats, <span class="function">mysqli_get_connection_stats, and are shown in mysqlnd section of the output of the <span class="function">phpinfo function as well.

This configuration setting enables all MySQL Native Driver statistics except those relating to memory management.

mysqlnd.collect_memory_statistics bool
Enable the collection of various memory statistics which can be accessed through mysqli_get_client_stats, <span class="function">mysqli_get_connection_stats, and are shown in mysqlnd section of the output of the <span class="function">phpinfo function as well.

This configuration setting enables the memory management statistics within the overall set of MySQL Native Driver statistics.

mysqlnd.debug string
Records communication from all extensions using mysqlnd to the specified log file.

The format of the directive is mysqlnd.debug = "option1[,parameter_option1][:option2[,parameter_option2]]".

The options for the format string are as follows:

  • A[,file] - Appends trace output to specified file. Also ensures that data is written after each write. This is done by closing and reopening the trace file (this is slow). It helps ensure a complete log file should the application crash.

  • a[,file] - Appends trace output to the specified file.

  • d - Enables output from DBUG_\<N> macros for the current state. May be followed by a list of keywords which selects output only for the DBUG macros with that keyword. An empty list of keywords implies output for all macros.

  • f[,functions] - Limits debugger actions to the specified list of functions. An empty list of functions implies that all functions are selected.

  • F - Marks each debugger output line with the name of the source file containing the macro causing the output.

  • i - Marks each debugger output line with the PID of the current process.

  • L - Marks each debugger output line with the name of the source file line number of the macro causing the output.

  • n - Marks each debugger output line with the current function nesting depth

  • o[,file] - Similar to a[,file] but overwrites old file, and does not append.

  • O[,file] - Similar to A[,file] but overwrites old file, and does not append.

  • t[,N] - Enables function control flow tracing. The maximum nesting depth is specified by N, and defaults to 200.

  • x - This option activates profiling.

  • m - Trace memory allocation and deallocation related calls.

Example:

d:t:x:O,/tmp/mysqlnd.trace

Note:

This feature is only available with a debug build of PHP. Works on Microsoft Windows if using a debug build of PHP and PHP was built using Microsoft Visual C version 9 and above.

mysqlnd.log_mask int
Defines which queries will be logged. The default 0, which disables logging. Define using an integer, and not with PHP constants. For example, a value of 48 (16 + 32) will log slow queries which either use 'no good index' (SERVER_QUERY_NO_GOOD_INDEX_USED = 16) or no index at all (SERVER_QUERY_NO_INDEX_USED = 32). A value of 2043 (1 + 2 + 8 + ... + 1024) will log all slow query types.

The types are as follows: SERVER_STATUS_IN_TRANS=1, SERVER_STATUS_AUTOCOMMIT=2, SERVER_MORE_RESULTS_EXISTS=8, SERVER_QUERY_NO_GOOD_INDEX_USED=16, SERVER_QUERY_NO_INDEX_USED=32, SERVER_STATUS_CURSOR_EXISTS=64, SERVER_STATUS_LAST_ROW_SENT=128, SERVER_STATUS_DB_DROPPED=256, SERVER_STATUS_NO_BACKSLASH_ESCAPES=512, and SERVER_QUERY_WAS_SLOW=1024.

mysqlnd.mempool_default_size int
Default size of the mysqlnd memory pool, which is used by result sets.

mysqlnd.net_read_timeout int
mysqlnd and the MySQL Client Library, libmysqlclient use different networking APIs. mysqlnd uses PHP streams, whereas libmysqlclient uses its own wrapper around the operating level network calls. PHP, by default, sets a read timeout of 60s for streams. This is set via php.ini, default_socket_timeout. This default applies to all streams that set no other timeout value. mysqlnd does not set any other value and therefore connections of long running queries can be disconnected after default_socket_timeout seconds resulting in an error message “2006 - MySQL Server has gone away”. The MySQL Client Library sets a default timeout of 24 * 3600 seconds (1 day) and waits for other timeouts to occur, such as TCP/IP timeouts. mysqlnd now uses the same very long timeout. The value is configurable through a new php.ini setting: mysqlnd.net_read_timeout. mysqlnd.net_read_timeout gets used by any extension (ext/mysql, ext/mysqli, PDO_MySQL) that uses mysqlnd. mysqlnd tells PHP Streams to use mysqlnd.net_read_timeout. Please note that there may be subtle differences between MYSQL_OPT_READ_TIMEOUT from the MySQL Client Library and PHP Streams, for example MYSQL_OPT_READ_TIMEOUT is documented to work only for TCP/IP connections and, prior to MySQL 5.1.2, only for Windows. PHP streams may not have this limitation. Please check the streams documentation, if in doubt.

mysqlnd.net_cmd_buffer_size int
mysqlnd allocates an internal command/network buffer of mysqlnd.net_cmd_buffer_size (in php.ini) bytes for every connection. If a MySQL Client Server protocol command, for example, COM_QUERY (“normal” query), does not fit into the buffer, mysqlnd will grow the buffer to the size required for sending the command. Whenever the buffer gets extended for one connection, command_buffer_too_small will be incremented by one.

If mysqlnd has to grow the buffer beyond its initial size of mysqlnd.net_cmd_buffer_size bytes for almost every connection, you should consider increasing the default size to avoid re-allocations.

The default buffer size is 2048 bytes in PHP 5.3.0. In later versions the default is 4096 bytes.

It is recommended that the buffer size be set to no less than 4096 bytes because mysqlnd also uses it when reading certain communication packet from MySQL. In PHP 5.3.0, mysqlnd will not grow the buffer if MySQL sends a packet that is larger than the current size of the buffer. As a consequence, mysqlnd is unable to decode the packet and the client application will get an error. There are only two situations when the packet can be larger than the 2048 bytes default of mysqlnd.net_cmd_buffer_size in PHP 5.3.0: the packet transports a very long error message, or the packet holds column meta data from COM_LIST_FIELD (mysql_list_fields() and the meta data come from a string column with a very long default value (>1900 bytes).

As of PHP 5.3.2 mysqlnd does not allow setting buffers smaller than 4096 bytes.

The value can also be set using mysqli_options(link, MYSQLI_OPT_NET_CMD_BUFFER_SIZE, size).

mysqlnd.net_read_buffer_size int
Maximum read chunk size in bytes when reading the body of a MySQL command packet. The MySQL client server protocol encapsulates all its commands in packets. The packets consist of a small header and a body with the actual payload. The size of the body is encoded in the header. mysqlnd reads the body in chunks of MIN(header.size, mysqlnd.net_read_buffer_size) bytes. If a packet body is larger than mysqlnd.net_read_buffer_size bytes, mysqlnd has to call read() multiple times.

The value can also be set using mysqli_options(link, MYSQLI_OPT_NET_READ_BUFFER_SIZE, size).

mysqlnd.sha256_server_public_key string
SHA-256 Authentication Plugin related. File with the MySQL server public RSA key.

Clients can either omit setting a public RSA key, specify the key through this PHP configuration setting or set the key at runtime using mysqli_options. If not public RSA key file is given by the client, then the key will be exchanged as part of the standard SHA-256 Authentication Plugin authentication procedure.

mysqlnd.trace_alloc string

mysqlnd.fetch_data_copy int
Enforce copying result sets from the internal result set buffers into PHP variables instead of using the default reference and copy-on-write logic. Please, see the memory management implementation notes for further details.

Copying result sets instead of having PHP variables reference them allows releasing the memory occupied for the PHP variables earlier. Depending on the user API code, the actual database quries and the size of their result sets this may reduce the memory footprint of mysqlnd.

Do not set if using PDO_MySQL. PDO_MySQL has not yet been updated to support the new fetch mode.

Incompatibilities

MySQL Native Driver is in most cases compatible with MySQL Client Library (libmysql). This section documents incompatibilities between these libraries.

  • Values of bit data type are returned as binary strings (e.g. "\0" or "\x1F") with libmysql and as decimal strings (e.g. "0" or "31") with mysqlnd. If you want the code to be compatible with both libraries then always return bit fields as numbers from MySQL with a query like this: SELECT bit + 0 FROM table.

Persistent Connections

Using Persistent Connections

If mysqli is used with mysqlnd, when a persistent connection is created it generates a COM_CHANGE_USER (mysql_change_user()) call on the server. This ensures that re-authentication of the connection takes place.

As there is some overhead associated with the COM_CHANGE_USER call, it is possible to switch this off at compile time. Reusing a persistent connection will then generate a COM_PING (mysql_ping) call to simply test the connection is reusable.

Generation of COM_CHANGE_USER can be switched off with the compile flag MYSQLI_NO_CHANGE_USER_ON_PCONNECT. For example:

shell# CFLAGS="-DMYSQLI_NO_CHANGE_USER_ON_PCONNECT" ./configure --with-mysql=/usr/local/mysql/ --with-mysqli=/usr/local/mysql/bin/mysql_config --with-pdo-mysql=/usr/local/mysql/bin/mysql_config --enable-debug && make clean && make -j6

Or alternatively:

shell# export CFLAGS="-DMYSQLI_NO_CHANGE_USER_ON_PCONNECT"
shell# configure --whatever-option
shell# make clean
shell# make

Note that only mysqli on mysqlnd uses COM_CHANGE_USER. Other extension-driver combinations use COM_PING on initial use of a persistent connection.

Statistics

Using Statistical Data

MySQL Native Driver contains support for gathering statistics on the communication between the client and the server. The statistics gathered are of two main types:

  • Client statistics

  • Connection statistics

If you are using the mysqli extension, these statistics can be obtained through two API calls:

  • mysqli_get_client_stats

  • mysqli_get_connection_stats

Note:

Statistics are aggregated among all extensions that use MySQL Native Driver. For example, when compiling both ext/mysql and ext/mysqli against MySQL Native Driver, both function calls of ext/mysql and ext/mysqli will change the statistics. There is no way to find out how much a certain API call of any extension that has been compiled against MySQL Native Driver has impacted a certain statistic. You can configure the PDO MySQL Driver, ext/mysql and ext/mysqli to optionally use the MySQL Native Driver. When doing so, all three extensions will change the statistics.

Accessing Client Statistics

To access client statistics, you need to call <span class="function">mysqli_get_client_stats. The function call does not require any parameters.

The function returns an associative array that contains the name of the statistic as the key and the statistical data as the value.

Client statistics can also be accessed by calling the <span class="function">phpinfo function.

Accessing Connection Statistics

To access connection statistics call <span class="function">mysqli_get_connection_stats. This takes the database connection handle as the parameter.

The function returns an associative array that contains the name of the statistic as the key and the statistical data as the value.

Buffered and Unbuffered Result Sets

Result sets can be buffered or unbuffered. Using default settings, ext/mysql and ext/mysqli work with buffered result sets for normal (non prepared statement) queries. Buffered result sets are cached on the client. After the query execution all results are fetched from the MySQL Server and stored in a cache on the client. The big advantage of buffered result sets is that they allow the server to free all resources allocated to a result set, once the results have been fetched by the client.

Unbuffered result sets on the other hand are kept much longer on the server. If you want to reduce memory consumption on the client, but increase load on the server, use unbuffered results. If you experience a high server load and the figures for unbuffered result sets are high, you should consider moving the load to the clients. Clients typically scale better than servers. “Load” does not only refer to memory buffers

  • the server also needs to keep other resources open, for example file handles and threads, before a result set can be freed.

Prepared Statements use unbuffered result sets by default. However, you can use mysqli_stmt_store_result to enable buffered result sets.

Statistics returned by MySQL Native Driver

The following tables show a list of statistics returned by the <span class="function">mysqli_get_client_stats and <span class="function">mysqli_get_connection_stats functions.

Returned mysqlnd statistics: Network
Statistic Scope Description Notes
bytes_sent Connection Number of bytes sent from PHP to the MySQL server Can be used to check the efficiency of the compression protocol
bytes_received Connection Number of bytes received from MySQL server Can be used to check the efficiency of the compression protocol
packets_sent Connection Number of MySQL Client Server protocol packets sent Used for debugging Client Server protocol implementation
packets_received Connection Number of MySQL Client Server protocol packets received Used for debugging Client Server protocol implementation
protocol_overhead_in Connection MySQL Client Server protocol overhead in bytes for incoming traffic. Currently only the Packet Header (4 bytes) is considered as overhead. protocol_overhead_in = packets_received * 4 Used for debugging Client Server protocol implementation
protocol_overhead_out Connection MySQL Client Server protocol overhead in bytes for outgoing traffic. Currently only the Packet Header (4 bytes) is considered as overhead. protocol_overhead_out = packets_sent * 4 Used for debugging Client Server protocol implementation
bytes_received_ok_packet Connection Total size of bytes of MySQL Client Server protocol OK packets received. OK packets can contain a status message. The length of the status message can vary and thus the size of an OK packet is not fixed. Used for debugging CS protocol implementation. Note that the total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
packets_received_ok Connection Number of MySQL Client Server protocol OK packets received. Used for debugging CS protocol implementation. Note that the total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
bytes_received_eof_packet Connection Total size in bytes of MySQL Client Server protocol EOF packets received. EOF can vary in size depending on the server version. Also, EOF can transport an error message. Used for debugging CS protocol implementation. Note that the total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
packets_received_eof Connection Number of MySQL Client Server protocol EOF packets. Like with other packet statistics the number of packets will be increased even if PHP does not receive the expected packet but, for example, an error message. Used for debugging CS protocol implementation. Note that the total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
bytes_received_rset_header_packet Connection Total size in bytes of MySQL Client Server protocol result set header packets. The size of the packets varies depending on the payload (LOAD LOCAL INFILE, INSERT, UPDATE, SELECT, error message). Used for debugging CS protocol implementation. Note that the total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
packets_received_rset_header Connection Number of MySQL Client Server protocol result set header packets. Used for debugging CS protocol implementation. Note that the total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
bytes_received_rset_field_meta_packet Connection Total size in bytes of MySQL Client Server protocol result set meta data (field information) packets. Of course the size varies with the fields in the result set. The packet may also transport an error or an EOF packet in case of COM_LIST_FIELDS. Only useful for debugging CS protocol implementation. Note that the total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
packets_received_rset_field_meta Connection Number of MySQL Client Server protocol result set meta data (field information) packets. Only useful for debugging CS protocol implementation. Note that the total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
bytes_received_rset_row_packet Connection Total size in bytes of MySQL Client Server protocol result set row data packets. The packet may also transport an error or an EOF packet. You can reverse engineer the number of error and EOF packets by subtracting rows_fetched_from_server_normal and rows_fetched_from_server_ps from bytes_received_rset_row_packet. Only useful for debugging CS protocol implementation. Note that the total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
packets_received_rset_row Connection Number of MySQL Client Server protocol result set row data packets and their total size in bytes. Only useful for debugging CS protocol implementation. Note that the total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
bytes_received_prepare_response_packet Connection Total size in bytes of MySQL Client Server protocol OK for Prepared Statement Initialization packets (prepared statement init packets). The packet may also transport an error. The packet size depends on the MySQL version: 9 bytes with MySQL 4.1 and 12 bytes from MySQL 5.0 on. There is no safe way to know how many errors happened. You may be able to guess that an error has occurred if, for example, you always connect to MySQL 5.0 or newer and, bytes_received_prepare_response_packet != packets_received_prepare_response * 12. See also ps_prepared_never_executed, ps_prepared_once_executed. Only useful for debugging CS protocol implementation. Note that the total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
packets_received_prepare_response Connection Number of MySQL Client Server protocol OK for Prepared Statement Initialization packets (prepared statement init packets). Only useful for debugging CS protocol implementation. Note that the total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
bytes_received_change_user_packet Connection Total size in bytes of MySQL Client Server protocol COM_CHANGE_USER packets. The packet may also transport an error or EOF. Only useful for debugging CS protocol implementation. Note that the total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
packets_received_change_user Connection Number of MySQL Client Server protocol COM_CHANGE_USER packets Only useful for debugging CS protocol implementation. Note that the total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
packets_sent_command Connection Number of MySQL Client Server protocol commands sent from PHP to MySQL. There is no way to know which specific commands and how many of them have been sent. At its best you can use it to check if PHP has sent any commands to MySQL to know if you can consider to disable MySQL support in your PHP binary. There is also no way to reverse engineer the number of errors that may have occurred while sending data to MySQL. The only error that is recorded is command_buffer_too_small (see below). Only useful for debugging CS protocol implementation.
bytes_received_real_data_normal Connection Number of bytes of payload fetched by the PHP client from mysqlnd using the text protocol. This is the size of the actual data contained in result sets that do not originate from prepared statements and which have been fetched by the PHP client. Note that although a full result set may have been pulled from MySQL by mysqlnd, this statistic only counts actual data pulled from mysqlnd by the PHP client. An example of a code sequence that will increase the value is as follows:
$mysqli = new mysqli();
$res = $mysqli->query("SELECT 'abc'");
$res->fetch_assoc();
$res->close();

Every fetch operation will increase the value.

The statistic will not be increased if the result set is only buffered on the client, but not fetched, such as in the following example:

$mysqli = new mysqli();
$res = $mysqli->query("SELECT 'abc'");
$res->close();

This statistic is available as of PHP version 5.3.4.

bytes_received_real_data_ps Connection Number of bytes of the payload fetched by the PHP client from mysqlnd using the prepared statement protocol. This is the size of the actual data contained in result sets that originate from prepared statements and which has been fetched by the PHP client. The value will not be increased if the result set is not subsequently read by the PHP client. Note that although a full result set may have been pulled from MySQL by mysqlnd, this statistic only counts actual data pulled from mysqlnd by the PHP client. See also bytes_received_real_data_normal. This statistic is available as of PHP version 5.3.4.

Result Set

Returned mysqlnd statistics: Result Set
Statistic Scope Description Notes
result_set_queries Connection Number of queries that have generated a result set. Examples of queries that generate a result set: SELECT, SHOW. The statistic will not be incremented if there is an error reading the result set header packet from the line. You may use it as an indirect measure for the number of queries PHP has sent to MySQL, for example, to identify a client that causes a high database load.
non_result_set_queries Connection Number of queries that did not generate a result set. Examples of queries that do not generate a result set: INSERT, UPDATE, LOAD DATA. The statistic will not be incremented if there is an error reading the result set header packet from the line. You may use it as an indirect measure for the number of queries PHP has sent to MySQL, for example, to identify a client that causes a high database load.
no_index_used Connection Number of queries that have generated a result set but did not use an index (see also mysqld start option –log-queries-not-using-indexes). If you want these queries to be reported you can use mysqli_report(MYSQLI_REPORT_INDEX) to make ext/mysqli throw an exception. If you prefer a warning instead of an exception use mysqli_report(MYSQLI_REPORT_INDEX ^ MYSQLI_REPORT_STRICT).  
bad_index_used Connection Number of queries that have generated a result set and did not use a good index (see also mysqld start option –log-slow-queries). If you want these queries to be reported you can use mysqli_report(MYSQLI_REPORT_INDEX) to make ext/mysqli throw an exception. If you prefer a warning instead of an exception use mysqli_report(MYSQLI_REPORT_INDEX ^ MYSQLI_REPORT_STRICT)
slow_queries Connection SQL statements that took more than long_query_time seconds to execute and required at least min_examined_row_limit rows to be examined. Not reported through mysqli_report
buffered_sets Connection Number of buffered result sets returned by “normal” queries. “Normal” means “not prepared statement” in the following notes. Examples of API calls that will buffer result sets on the client: mysql_query, mysqli_query, mysqli_store_result, mysqli_stmt_get_result. Buffering result sets on the client ensures that server resources are freed as soon as possible and it makes result set scrolling easier. The downside is the additional memory consumption on the client for buffering data. Note that mysqlnd (unlike the MySQL Client Library) respects the PHP memory limit because it uses PHP internal memory management functions to allocate memory. This is also the reason why memory_get_usage reports a higher memory consumption when using mysqlnd instead of the MySQL Client Library. memory_get_usage does not measure the memory consumption of the MySQL Client Library at all because the MySQL Client Library does not use PHP internal memory management functions monitored by the function!
unbuffered_sets Connection Number of unbuffered result sets returned by normal (non prepared statement) queries. Examples of API calls that will not buffer result sets on the client: mysqli_use_result
ps_buffered_sets Connection Number of buffered result sets returned by prepared statements. By default prepared statements are unbuffered. Examples of API calls that will buffer result sets on the client: mysqli_stmt_store_result
ps_unbuffered_sets Connection Number of unbuffered result sets returned by prepared statements. By default prepared statements are unbuffered.
flushed_normal_sets Connection Number of result sets from normal (non prepared statement) queries with unread data which have been flushed silently for you. Flushing happens only with unbuffered result sets. Unbuffered result sets must be fetched completely before a new query can be run on the connection otherwise MySQL will throw an error. If the application does not fetch all rows from an unbuffered result set, mysqlnd does implicitly fetch the result set to clear the line. See also rows_skipped_normal, rows_skipped_ps. Some possible causes for an implicit flush:
  • Faulty client application

  • Client stopped reading after it found what it was looking for but has made MySQL calculate more records than needed

  • Client application has stopped unexpectedly

flushed_ps_sets Connection Number of result sets from prepared statements with unread data which have been flushed silently for you. Flushing happens only with unbuffered result sets. Unbuffered result sets must be fetched completely before a new query can be run on the connection otherwise MySQL will throw an error. If the application does not fetch all rows from an unbuffered result set, mysqlnd does implicitly fetch the result set to clear the line. See also rows_skipped_normal, rows_skipped_ps. Some possible causes for an implicit flush:
  • Faulty client application

  • Client stopped reading after it found what it was looking for but has made MySQL calculate more records than needed

  • Client application has stopped unexpectedly

ps_prepared_never_executed Connection Number of statements prepared but never executed. Prepared statements occupy server resources. You should not prepare a statement if you do not plan to execute it.
ps_prepared_once_executed Connection Number of prepared statements executed only one. One of the ideas behind prepared statements is that the same query gets executed over and over again (with different parameters) and some parsing and other preparation work can be saved, if statement execution is split up in separate prepare and execute stages. The idea is to prepare once and “cache” results, for example, the parse tree to be reused during multiple statement executions. If you execute a prepared statement only once the two stage processing can be inefficient compared to “normal” queries because all the caching means extra work and it takes (limited) server resources to hold the cached information. Consequently, prepared statements that are executed only once may cause performance hurts.
rows_fetched_from_server_normal, rows_fetched_from_server_ps Connection Total number of result set rows successfully fetched from MySQL regardless if the client application has consumed them or not. Some of the rows may not have been fetched by the client application but have been flushed implicitly. See also packets_received_rset_row
rows_buffered_from_client_normal, rows_buffered_from_client_ps Connection Total number of successfully buffered rows originating from a "normal" query or a prepared statement. This is the number of rows that have been fetched from MySQL and buffered on client. Note that there are two distinct statistics on rows that have been buffered (MySQL to mysqlnd internal buffer) and buffered rows that have been fetched by the client application (mysqlnd internal buffer to client application). If the number of buffered rows is higher than the number of fetched buffered rows it can mean that the client application runs queries that cause larger result sets than needed resulting in rows not read by the client. Examples of queries that will buffer results: mysqli_query, mysqli_store_result
rows_fetched_from_client_normal_buffered, rows_fetched_from_client_ps_buffered Connection Total number of rows fetched by the client from a buffered result set created by a normal query or a prepared statement.  
rows_fetched_from_client_normal_unbuffered, rows_fetched_from_client_ps_unbuffered Connection Total number of rows fetched by the client from a unbuffered result set created by a "normal" query or a prepared statement.  
rows_fetched_from_client_ps_cursor Connection Total number of rows fetch by the client from a cursor created by a prepared statement.  
rows_skipped_normal, rows_skipped_ps Connection Reserved for future use (currently not supported)  
copy_on_write_saved, copy_on_write_performed Process With mysqlnd, variables returned by the extensions point into mysqlnd internal network result buffers. If you do not change the variables, fetched data will be kept only once in memory. If you change the variables, mysqlnd has to perform a copy-on-write to protect the internal network result buffers from being changed. With the MySQL Client Library you always hold fetched data twice in memory. Once in the internal MySQL Client Library buffers and once in the variables returned by the extensions. In theory mysqlnd can save up to 40% memory. However, note that the memory saving cannot be measured using memory_get_usage.  
explicit_free_result, implicit_free_result Connection, Process (only during prepared statement cleanup) Total number of freed result sets. The free is always considered explicit but for result sets created by an init command, for example, mysqli_options(MYSQLI_INIT_COMMAND , ...)
proto_text_fetched_null, proto_text_fetched_bit, proto_text_fetched_tinyint proto_text_fetched_short, proto_text_fetched_int24, proto_text_fetched_int proto_text_fetched_bigint, proto_text_fetched_decimal, proto_text_fetched_float proto_text_fetched_double, proto_text_fetched_date, proto_text_fetched_year proto_text_fetched_time, proto_text_fetched_datetime, proto_text_fetched_timestamp proto_text_fetched_string, proto_text_fetched_blob, proto_text_fetched_enum proto_text_fetched_set, proto_text_fetched_geometry, proto_text_fetched_other Connection Total number of columns of a certain type fetched from a normal query (MySQL text protocol). Mapping from C API / MySQL meta data type to statistics name:
  • MYSQL_TYPE_NULL - proto_text_fetched_null

  • MYSQL_TYPE_BIT - proto_text_fetched_bit

  • MYSQL_TYPE_TINY - proto_text_fetched_tinyint

  • MYSQL_TYPE_SHORT - proto_text_fetched_short

  • MYSQL_TYPE_INT24 - proto_text_fetched_int24

  • MYSQL_TYPE_LONG - proto_text_fetched_int

  • MYSQL_TYPE_LONGLONG - proto_text_fetched_bigint

  • MYSQL_TYPE_DECIMAL, MYSQL_TYPE_NEWDECIMAL - proto_text_fetched_decimal

  • MYSQL_TYPE_FLOAT - proto_text_fetched_float

  • MYSQL_TYPE_DOUBLE - proto_text_fetched_double

  • MYSQL_TYPE_DATE, MYSQL_TYPE_NEWDATE - proto_text_fetched_date

  • MYSQL_TYPE_YEAR - proto_text_fetched_year

  • MYSQL_TYPE_TIME - proto_text_fetched_time

  • MYSQL_TYPE_DATETIME - proto_text_fetched_datetime

  • MYSQL_TYPE_TIMESTAMP - proto_text_fetched_timestamp

  • MYSQL_TYPE_STRING, MYSQL_TYPE_VARSTRING, MYSQL_TYPE_VARCHAR - proto_text_fetched_string

  • MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB - proto_text_fetched_blob

  • MYSQL_TYPE_ENUM - proto_text_fetched_enum

  • MYSQL_TYPE_SET - proto_text_fetched_set

  • MYSQL_TYPE_GEOMETRY - proto_text_fetched_geometry

  • Any MYSQL_TYPE_* not listed before (there should be none) - proto_text_fetched_other

Note that the MYSQL_*-type constants may not be associated with the very same SQL column types in every version of MySQL.

proto_binary_fetched_null, proto_binary_fetched_bit, proto_binary_fetched_tinyint proto_binary_fetched_short, proto_binary_fetched_int24, proto_binary_fetched_int, proto_binary_fetched_bigint, proto_binary_fetched_decimal, proto_binary_fetched_float, proto_binary_fetched_double, proto_binary_fetched_date, proto_binary_fetched_year, proto_binary_fetched_time, proto_binary_fetched_datetime, proto_binary_fetched_timestamp, proto_binary_fetched_string, proto_binary_fetched_blob, proto_binary_fetched_enum, proto_binary_fetched_set, proto_binary_fetched_geometry, proto_binary_fetched_other Connection Total number of columns of a certain type fetched from a prepared statement (MySQL binary protocol). For type mapping see proto_text_* described in the preceding text.
Returned mysqlnd statistics: Connection
Statistic Scope Description Notes
connect_success, connect_failure Connection Total number of successful / failed connection attempt. Reused connections and all other kinds of connections are included.
reconnect Process Total number of (real_)connect attempts made on an already opened connection handle. The code sequence $link = new mysqli(...); $link->real_connect(...) will cause a reconnect. But $link = new mysqli(...); $link->connect(...) will not because $link->connect(...) will explicitly close the existing connection before a new connection is established.
pconnect_success Connection Total number of successful persistent connection attempts. Note that connect_success holds the sum of successful persistent and non-persistent connection attempts. The number of successful non-persistent connection attempts is connect_success - pconnect_success.
active_connections Connection Total number of active persistent and non-persistent connections.  
active_persistent_connections Connection Total number of active persistent connections. The total number of active non-persistent connections is active_connections - active_persistent_connections.
explicit_close Connection Total number of explicitly closed connections (ext/mysqli only). Examples of code snippets that cause an explicit close :
$link = new mysqli(...); $link->close(...)
$link = new mysqli(...); $link->connect(...)
implicit_close Connection Total number of implicitly closed connections (ext/mysqli only). Examples of code snippets that cause an implicit close :
  • $link = new mysqli(...); $link->real_connect(...)

  • unset($link)

  • Persistent connection: pooled connection has been created with real_connect and there may be unknown options set - close implicitly to avoid returning a connection with unknown options

  • Persistent connection: ping/change_user fails and ext/mysqli closes the connection

  • end of script execution: close connections that have not been closed by the user

disconnect_close Connection Connection failures indicated by the C API call mysql_real_connect during an attempt to establish a connection. It is called disconnect_close because the connection handle passed to the C API call will be closed.
in_middle_of_command_close Process A connection has been closed in the middle of a command execution (outstanding result sets not fetched, after sending a query and before retrieving an answer, while fetching data, while transferring data with LOAD DATA). Unless you use asynchronous queries this should only happen if your script stops unexpectedly and PHP shuts down the connections for you.
init_command_executed_count Connection Total number of init command executions, for example, mysqli_options(MYSQLI_INIT_COMMAND , ...). The number of successful executions is init_command_executed_count - init_command_failed_count.
init_command_failed_count Connection Total number of failed init commands.  
Returned mysqlnd statistics: COM_* Command
Statistic Scope Description Notes
com_quit, com_init_db, com_query, com_field_list, com_create_db, com_drop_db, com_refresh, com_shutdown, com_statistics, com_process_info, com_connect, com_process_kill, com_debug, com_ping, com_time, com_delayed_insert, com_change_user, com_binlog_dump, com_table_dump, com_connect_out, com_register_slave, com_stmt_prepare, com_stmt_execute, com_stmt_send_long_data, com_stmt_close, com_stmt_reset, com_stmt_set_option, com_stmt_fetch, com_daemon Connection Total number of attempts to send a certain COM_* command from PHP to MySQL.

The statistics are incremented after checking the line and immediately before sending the corresponding MySQL client server protocol packet. If mysqlnd fails to send the packet over the wire the statistics will not be decremented. In case of a failure mysqlnd emits a PHP warning “Error while sending %s packet. PID=%d.”

Usage examples:

  • Check if PHP sends certain commands to MySQL, for example, check if a client sends COM_PROCESS_KILL

  • Calculate the average number of prepared statement executions by comparing COM_EXECUTE with COM_PREPARE

  • Check if PHP has run any non-prepared SQL statements by checking if COM_QUERY is zero

  • Identify PHP scripts that run an excessive number of SQL statements by checking COM_QUERY and COM_EXECUTE

Miscellaneous

Returned mysqlnd statistics: Miscellaneous
Statistic Scope Description Notes
explicit_stmt_close, implicit_stmt_close Process Total number of close prepared statements. A close is always considered explicit but for a failed prepare.
mem_emalloc_count, mem_emalloc_ammount, mem_ecalloc_count, mem_ecalloc_ammount, mem_erealloc_count, mem_erealloc_ammount, mem_efree_count, mem_malloc_count, mem_malloc_ammount, mem_calloc_count, mem_calloc_ammount, mem_realloc_count, mem_realloc_ammount, mem_free_count Process Memory management calls. Development only.
command_buffer_too_small Connection Number of network command buffer extensions while sending commands from PHP to MySQL.

mysqlnd allocates an internal command/network buffer of mysqlnd.net_cmd_buffer_size (php.ini) bytes for every connection. If a MySQL Client Server protocol command, for example, COM_QUERY (normal query), does not fit into the buffer, mysqlnd will grow the buffer to what is needed for sending the command. Whenever the buffer gets extended for one connection command_buffer_too_small will be incremented by one.

If mysqlnd has to grow the buffer beyond its initial size of mysqlnd.net_cmd_buffer_size (php.ini) bytes for almost every connection, you should consider to increase the default size to avoid re-allocations.

The default buffer size is 2048 bytes in PHP 5.3.0. In future versions the default will be 4kB or larger. The default can changed either through the php.ini setting mysqlnd.net_cmd_buffer_size or using mysqli_options(MYSQLI_OPT_NET_CMD_BUFFER_SIZE, int size).

It is recommended to set the buffer size to no less than 4096 bytes because mysqlnd also uses it when reading certain communication packet from MySQL. In PHP 5.3.0, mysqlnd will not grow the buffer if MySQL sends a packet that is larger than the current size of the buffer. As a consequence mysqlnd is unable to decode the packet and the client application will get an error. There are only two situations when the packet can be larger than the 2048 bytes default of mysqlnd.net_cmd_buffer_size in PHP 5.3.0: the packet transports a very long error message or the packet holds column meta data from COM_LIST_FIELD (mysql_list_fields) and the meta data comes from a string column with a very long default value (>1900 bytes). No bug report on this exists - it should happen rarely.

As of PHP 5.3.2 mysqlnd does not allow setting buffers smaller than 4096 bytes.

connection_reused      

Notes

This section provides a collection of miscellaneous notes on MySQL Native Driver usage.

  • Using mysqlnd means using PHP streams for underlying connectivity. For mysqlnd, the PHP streams documentation (Streams) should be consulted on such details as timeout settings, not the documentation for the MySQL Client Library.

Memory management

Introduction

The MySQL Native Driver manages memory different than the MySQL Client Library. The libraries differ in the way memory is allocated and released, how memory is allocated in chunks while reading results from MySQL, which debug and development options exist, and how results read from MySQL are linked to PHP user variables.

The following notes are intended as an introduction and summary to users interested at understanding the MySQL Native Driver at the C code level.

Memory management functions used

All memory allocation and deallocation is done using the PHP memory management functions. Therefore, the memory consumption of mysqlnd can be tracked using PHP API calls, such as <span class="function">memory_get_usage. Because memory is allocated and released using the PHP memory management, the changes may not immediately become visible at the operating system level. The PHP memory management acts as a proxy which may delay releasing memory towards the system. Due to this, comparing the memory usage of the MySQL Native Driver and the MySQL Client Library is difficult. The MySQL Client Library is using the operating system memory management calls directly, hence the effects can be observed immediately at the operating system level.

Any memory limit enforced by PHP also affects the MySQL Native Driver. This may cause out of memory errors when fetching large result sets that exceed the size of the remaining memory made available by PHP. Because the MySQL Client Library is not using PHP memory management functions, it does not comply to any PHP memory limit set. If using the MySQL Client Library, depending on the deployment model, the memory footprint of the PHP process may grow beyond the PHP memory limit. But also PHP scripts may be able to process larger result sets as parts of the memory allocated to hold the result sets are beyond the control of the PHP engine.

PHP memory management functions are invoked by the MySQL Native Driver through a lightweight wrapper. Among others, the wrapper makes debugging easier.

Handling of result sets

The various MySQL Server and the various client APIs differentiate between buffered and unbuffered result sets. Unbuffered result sets are transferred row-by-row from MySQL to the client as the client iterates over the results. Buffered results are fetched in their entirety by the client library before passing them on to the client.

The MySQL Native Driver is using PHP Streams for the network communication with the MySQL Server. Results sent by MySQL are fetched from the PHP Streams network buffers into the result buffer of mysqlnd. The result buffer is made of zvals. In a second step the results are made available to the PHP script. This final transfer from the result buffer into PHP variables impacts the memory consumption and is mostly noticeable when using buffered result sets.

By default the MySQL Native Driver tries to avoid holding buffered results twice in memory. Results are kept only once in the internal result buffers and their zvals. When results are fetched into PHP variables by the PHP script, the variables will reference the internal result buffers. Database query results are not copied and kept in memory only once. Should the user modify the contents of a variable holding the database results a copy-on-write must be performed to avoid changing the referenced internal result buffer. The contents of the buffer must not be modified because the user may decide to read the result set a second time. The copy-on-write mechanism is implemented using an additional reference management list and the use of standard zval reference counters. Copy-on-write must also be done if the user reads a result set into PHP variables and frees a result set before the variables are unset.

Generally speaking, this pattern works well for scripts that read a result set once and do not modify variables holding results. Its major drawback is the memory overhead caused by the additional reference management which comes primarily from the fact that user variables holding results cannot be entirely released until the mysqlnd reference management stops referencing them. The MySQL Native driver removes the reference to the user variables when the result set is freed or a copy-on-write is performed. An observer will see the total memory consumption grow until the result set is released. Use the statistics to check whether a script does release result sets explicitly or the driver is does implicit releases and thus memory is used for a time longer than necessary. Statistics also help to see how many copy-on-write operations happened.

A PHP script reading many small rows of a buffered result set using a code snippet equal or equivalent to while ($row = $res->fetch_assoc()) { ... } may optimize memory consumption by requesting copies instead of references. Albeit requesting copies means keeping results twice in memory, it allows PHP to free the copy contained in $row as the result set is being iterated and prior to releasing the result set itself. On a loaded server optimizing peak memory usage may help improving the overall system performance although for an individual script the copy approach may be slower due to additional allocations and memory copy operations.

The copy mode can be enforced by setting mysqlnd.fetch_data_copy=1.

Monitoring and debugging

There are multiple ways of tracking the memory usage of the MySQL Native Driver. If the goal is to get a quick high level overview or to verify the memory efficiency of PHP scripts, then check the statistics collected by the library. The statistics allow you, for example, to catch SQL statements which generate more results than are processed by a PHP script.

The debug trace log can be configured to record memory management calls. This helps to see when memory is allocated or free'd. However, the size of the requested memory chunks may not be listed.

Some, recent versions of the MySQL Native Driver feature the emulation of random out of memory situations. This feature is meant to be used by the C developers of the library or mysqlnd plugin authors only. Please, search the source code for corresponding PHP configuration settings and further details. The feature is considered private and may be modified at any time without prior notice.

MySQL Native Driver Plugin API

目录

The MySQL Native Driver Plugin API is a feature of MySQL Native Driver, or mysqlnd. Mysqlnd plugins operate in the layer between PHP applications and the MySQL server. This is comparable to MySQL Proxy. MySQL Proxy operates on a layer between any MySQL client application, for example, a PHP application and, the MySQL server. Mysqlnd plugins can undertake typical MySQL Proxy tasks such as load balancing, monitoring and performance optimizations. Due to the different architecture and location, mysqlnd plugins do not have some of MySQL Proxy's disadvantages. For example, with plugins, there is no single point of failure, no dedicated proxy server to deploy, and no new programming language to learn (Lua).

A mysqlnd plugin can be thought of as an extension to mysqlnd. Plugins can intercept the majority of mysqlnd functions. The mysqlnd functions are called by the PHP MySQL extensions such as ext/mysql, ext/mysqli, and PDO_MYSQL. As a result, it is possible for a mysqlnd plugin to intercept all calls made to these extensions from the client application.

Internal mysqlnd function calls can also be intercepted, or replaced. There are no restrictions on manipulating mysqlnd internal function tables. It is possible to set things up so that when certain mysqlnd functions are called by the extensions that use mysqlnd, the call is directed to the appropriate function in the mysqlnd plugin. The ability to manipulate mysqlnd internal function tables in this way allows maximum flexibility for plugins.

Mysqlnd plugins are in fact PHP Extensions, written in C, that use the mysqlnd plugin API (which is built into MySQL Native Driver, mysqlnd). Plugins can be made 100% transparent to PHP applications. No application changes are needed because plugins operate on a different layer. The mysqlnd plugin can be thought of as operating in a layer below mysqlnd.

The following list represents some possible applications of mysqlnd plugins.

  • Load Balancing

    • Read/Write Splitting. An example of this is the PECL/mysqlnd_ms (Master Slave) extension. This extension splits read/write queries for a replication setup.

    • Failover

    • Round-Robin, least loaded

  • Monitoring

    • Query Logging

    • Query Analysis

    • Query Auditing. An example of this is the PECL/mysqlnd_sip (SQL Injection Protection) extension. This extension inspects queries and executes only those that are allowed according to a ruleset.

  • Performance

    • Caching. An example of this is the PECL/mysqlnd_qc (Query Cache) extension.

    • Throttling

    • Sharding. An example of this is the PECL/mysqlnd_mc (Multi Connect) extension. This extension will attempt to split a SELECT statement into n-parts, using SELECT ... LIMIT part_1, SELECT LIMIT part_n. It sends the queries to distinct MySQL servers and merges the result at the client.

MySQL Native Driver Plugins Available

There are a number of mysqlnd plugins already available. These include:

  • PECL/mysqlnd_mc - Multi Connect plugin.

  • PECL/mysqlnd_ms - Master Slave plugin.

  • PECL/mysqlnd_qc - Query Cache plugin.

  • PECL/mysqlnd_pscache - Prepared Statement Handle Cache plugin.

  • PECL/mysqlnd_sip - SQL Injection Protection plugin.

  • PECL/mysqlnd_uh - User Handler plugin.

A comparison of mysqlnd plugins with MySQL Proxy

Mysqlnd plugins and MySQL Proxy are different technologies using different approaches. Both are valid tools for solving a variety of common tasks such as load balancing, monitoring, and performance enhancements. An important difference is that MySQL Proxy works with all MySQL clients, whereas mysqlnd plugins are specific to PHP applications.

As a PHP Extension, a mysqlnd plugin gets installed on the PHP application server, along with the rest of PHP. MySQL Proxy can either be run on the PHP application server or can be installed on a dedicated machine to handle multiple PHP application servers.

Deploying MySQL Proxy on the application server has two advantages:

  1. No single point of failure

  2. Easy to scale out (horizontal scale out, scale by client)

MySQL Proxy (and mysqlnd plugins) can solve problems easily which otherwise would have required changes to existing applications.

However, MySQL Proxy does have some disadvantages:

  • MySQL Proxy is a new component and technology to master and deploy.

  • MySQL Proxy requires knowledge of the Lua scripting language.

MySQL Proxy can be customized with C and Lua programming. Lua is the preferred scripting language of MySQL Proxy. For most PHP experts Lua is a new language to learn. A mysqlnd plugin can be written in C. It is also possible to write plugins in PHP using » PECL/mysqlnd_uh.

MySQL Proxy runs as a daemon - a background process. MySQL Proxy can recall earlier decisions, as all state can be retained. However, a mysqlnd plugin is bound to the request-based lifecycle of PHP. MySQL Proxy can also share one-time computed results among multiple application servers. A mysqlnd plugin would need to store data in a persistent medium to be able to do this. Another daemon would need to be used for this purpose, such as Memcache. This gives MySQL Proxy an advantage in this case.

MySQL Proxy works on top of the wire protocol. With MySQL Proxy you have to parse and reverse engineer the MySQL Client Server Protocol. Actions are limited to those that can be achieved by manipulating the communication protocol. If the wire protocol changes (which happens very rarely) MySQL Proxy scripts would need to be changed as well.

Mysqlnd plugins work on top of the C API, which mirrors the libmysqlclient client. This C API is basically a wrapper around the MySQL Client Server protocol, or wire protocol, as it is sometimes called. You can intercept all C API calls. PHP makes use of the C API, therefore you can hook all PHP calls, without the need to program at the level of the wire protocol.

Mysqlnd implements the wire protocol. Plugins can therefore parse, reverse engineer, manipulate and even replace the communication protocol. However, this is usually not required.

As plugins allow you to create implementations that use two levels (C API and wire protocol), they have greater flexibility than MySQL Proxy. If a mysqlnd plugin is implemented using the C API, any subsequent changes to the wire protocol do not require changes to the plugin itself.

Obtaining the mysqlnd plugin API

The mysqlnd plugin API is simply part of the MySQL Native Driver PHP extension, ext/mysqlnd. Development started on the mysqlnd plugin API in December 2009. It is developed as part of the PHP source repository, and as such is available to the public either via Git, or through source snapshot downloads.

The following table shows PHP versions and the corresponding mysqlnd version contained within.

PHP Version MySQL Native Driver version
5.3.0 5.0.5
5.3.1 5.0.5
5.3.2 5.0.7
5.3.3 5.0.7
5.3.4 5.0.7

Plugin developers can determine the mysqlnd version through accessing MYSQLND_VERSION, which is a string of the format “mysqlnd 5.0.7-dev - 091210 - $Revision: 300535”, or through MYSQLND_VERSION_ID, which is an integer such as 50007. Developers can calculate the version number as follows:

Version (part) Example
Major*10000 5*10000 = 50000
Minor*100 0*100 = 0
Patch 7 = 7
MYSQLND_VERSION_ID 50007

During development, developers should refer to the mysqlnd version number for compatibility and version tests, as several iterations of mysqlnd could occur during the lifetime of a PHP development branch with a single PHP version number.

MySQL Native Driver Plugin Architecture

This section provides an overview of the mysqlnd plugin architecture.

MySQL Native Driver Overview

Before developing mysqlnd plugins, it is useful to know a little of how mysqlnd itself is organized. Mysqlnd consists of the following modules:

Modules Statistics mysqlnd_statistics.c
Connection mysqlnd.c
Resultset mysqlnd_result.c
Resultset Metadata mysqlnd_result_meta.c
Statement mysqlnd_ps.c
Network mysqlnd_net.c
Wire protocol mysqlnd_wireprotocol.c

C Object Oriented Paradigm

At the code level, mysqlnd uses a C pattern for implementing object orientation.

In C you use a struct to represent an object. Members of the struct represent object properties. Struct members pointing to functions represent methods.

Unlike with other languages such as C++ or Java, there are no fixed rules on inheritance in the C object oriented paradigm. However, there are some conventions that need to be followed that will be discussed later.

The PHP Life Cycle

When considering the PHP life cycle there are two basic cycles:

  • PHP engine startup and shutdown cycle

  • Request cycle

When the PHP engine starts up it will call the module initialization (MINIT) function of each registered extension. This allows each module to setup variables and allocate resources that will exist for the lifetime of the PHP engine process. When the PHP engine shuts down it will call the module shutdown (MSHUTDOWN) function of each extension.

During the lifetime of the PHP engine it will receive a number of requests. Each request constitutes another life cycle. On each request the PHP engine will call the request initialization function of each extension. The extension can perform any variable setup and resource allocation required for request processing. As the request cycle ends the engine calls the request shutdown (RSHUTDOWN) function of each extension so the extension can perform any cleanup required.

How a plugin works

A mysqlnd plugin works by intercepting calls made to mysqlnd by extensions that use mysqlnd. This is achieved by obtaining the mysqlnd function table, backing it up, and replacing it by a custom function table, which calls the functions of the plugin as required.

The following code shows how the mysqlnd function table is replaced:

/* a place to store original function table */
struct st_mysqlnd_conn_methods org_methods;

void minit_register_hooks(TSRMLS_D) {
  /* active function table */
  struct st_mysqlnd_conn_methods * current_methods
    = mysqlnd_conn_get_methods();

  /* backup original function table */
  memcpy(&org_methods, current_methods,
    sizeof(struct st_mysqlnd_conn_methods);

  /* install new methods */
  current_methods->query = MYSQLND_METHOD(my_conn_class, query);
}

Connection function table manipulations must be done during Module Initialization (MINIT). The function table is a global shared resource. In an multi-threaded environment, with a TSRM build, the manipulation of a global shared resource during the request processing will almost certainly result in conflicts.

Note:

Do not use any fixed-size logic when manipulating the mysqlnd function table: new methods may be added at the end of the function table. The function table may change at any time in the future.

Calling parent methods

If the original function table entries are backed up, it is still possible to call the original function table entries - the parent methods.

In some cases, such as for Connection::stmt_init(), it is vital to call the parent method prior to any other activity in the derived method.

MYSQLND_METHOD(my_conn_class, query)(MYSQLND *conn,
  const char *query, unsigned int query_len TSRMLS_DC) {

  php_printf("my_conn_class::query(query = %s)\n", query);

  query = "SELECT 'query rewritten' FROM DUAL";
  query_len = strlen(query);

  return org_methods.query(conn, query, query_len); /* return with call to parent */
}

Extending properties

A mysqlnd object is represented by a C struct. It is not possible to add a member to a C struct at run time. Users of mysqlnd objects cannot simply add properties to the objects.

Arbitrary data (properties) can be added to a mysqlnd objects using an appropriate function of the mysqlnd_plugin_get_plugin_\<object>_data() family. When allocating an object mysqlnd reserves space at the end of the object to hold a void * pointer to arbitrary data. mysqlnd reserves space for one void * pointer per plugin.

The following table shows how to calculate the position of the pointer for a specific plugin:

Memory address Contents
0 Beginning of the mysqlnd object C struct
n End of the mysqlnd object C struct
n + (m x sizeof(void*)) void* to object data of the m-th plugin

If you plan to subclass any of the mysqlnd object constructors, which is allowed, you must keep this in mind!

The following code shows extending properties:

/* any data we want to associate */
typedef struct my_conn_properties {
  unsigned long query_counter;
} MY_CONN_PROPERTIES;

/* plugin id */
unsigned int my_plugin_id;

void minit_register_hooks(TSRMLS_D) {
  /* obtain unique plugin ID */
  my_plugin_id = mysqlnd_plugin_register();
  /* snip - see Extending Connection: methods */
}

static MY_CONN_PROPERTIES** get_conn_properties(const MYSQLND *conn TSRMLS_DC) {
  MY_CONN_PROPERTIES** props;
  props = (MY_CONN_PROPERTIES**)mysqlnd_plugin_get_plugin_connection_data(
    conn, my_plugin_id);
  if (!props || !(*props)) {
    *props = mnd_pecalloc(1, sizeof(MY_CONN_PROPERTIES), conn->persistent);
    (*props)->query_counter = 0;
  }
  return props;
}

The plugin developer is responsible for the management of plugin data memory.

Use of the mysqlnd memory allocator is recommended for plugin data. These functions are named using the convention: mnd_*loc(). The mysqlnd allocator has some useful features, such as the ability to use a debug allocator in a non-debug build.

  When to subclass? Each instance has its own private function table? How to subclass?
Connection (MYSQLND) MINIT No mysqlnd_conn_get_methods()
Resultset (MYSQLND_RES) MINIT or later Yes mysqlnd_result_get_methods() or object method function table manipulation
Resultset Meta (MYSQLND_RES_METADATA) MINIT No mysqlnd_result_metadata_get_methods()
Statement (MYSQLND_STMT) MINIT No mysqlnd_stmt_get_methods()
Network (MYSQLND_NET) MINIT or later Yes mysqlnd_net_get_methods() or object method function table manipulation
Wire protocol (MYSQLND_PROTOCOL) MINIT or later Yes mysqlnd_protocol_get_methods() or object method function table manipulation

You must not manipulate function tables at any time later than MINIT if it is not allowed according to the above table.

Some classes contain a pointer to the method function table. All instances of such a class will share the same function table. To avoid chaos, in particular in threaded environments, such function tables must only be manipulated during MINIT.

Other classes use copies of a globally shared function table. The class function table copy is created together with the object. Each object uses its own function table. This gives you two options: you can manipulate the default function table of an object at MINIT, and you can additionally refine methods of an object without impacting other instances of the same class.

The advantage of the shared function table approach is performance. There is no need to copy a function table for each and every object.

Constructor status
Type Allocation, construction, reset Can be modified? Caller
Connection (MYSQLND) mysqlnd_init() No mysqlnd_connect()
Resultset(MYSQLND_RES)

Allocation:

  • Connection::result_init()

Reset and re-initialized during:

  • Result::use_result()

  • Result::store_result

Yes, but call parent!
  • Connection::list_fields()

  • Statement::get_result()

  • Statement::prepare() (Metadata only)

  • Statement::resultMetaData()

Resultset Meta (MYSQLND_RES_METADATA) Connection::result_meta_init() Yes, but call parent! Result::read_result_metadata()
Statement (MYSQLND_STMT) Connection::stmt_init() Yes, but call parent! Connection::stmt_init()
Network (MYSQLND_NET) mysqlnd_net_init() No Connection::init()
Wire protocol (MYSQLND_PROTOCOL) mysqlnd_protocol_init() No Connection::init()

It is strongly recommended that you do not entirely replace a constructor. The constructors perform memory allocations. The memory allocations are vital for the mysqlnd plugin API and the object logic of mysqlnd. If you do not care about warnings and insist on hooking the constructors, you should at least call the parent constructor before doing anything in your constructor.

Regardless of all warnings, it can be useful to subclass constructors. Constructors are the perfect place for modifying the function tables of objects with non-shared object tables, such as Resultset, Network, Wire Protocol.

Type Derived method must call parent? Destructor
Connection yes, after method execution free_contents(), end_psession()
Resultset yes, after method execution free_result()
Resultset Meta yes, after method execution free()
Statement yes, after method execution dtor(), free_stmt_content()
Network yes, after method execution free()
Wire protocol yes, after method execution free()

The destructors are the appropriate place to free properties, mysqlnd_plugin_get_plugin_<span class="replaceable">\<object>_data().

The listed destructors may not be equivalent to the actual mysqlnd method freeing the object itself. However, they are the best possible place for you to hook in and free your plugin data. As with constructors you may replace the methods entirely but this is not recommended. If multiple methods are listed in the above table you will need to hook all of the listed methods and free your plugin data in whichever method is called first by mysqlnd.

The recommended method for plugins is to simply hook the methods, free your memory and call the parent implementation immediately following this.

Caution

Due to a bug in PHP versions 5.3.0 to 5.3.3, plugins do not associate plugin data with a persistent connection. This is because ext/mysql and ext/mysqli do not trigger all the necessary mysqlnd end_psession() method calls and the plugin may therefore leak memory. This has been fixed in PHP 5.3.4.

The mysqlnd plugin API

The following is a list of functions provided in the mysqlnd plugin API:

  • mysqlnd_plugin_register()

  • mysqlnd_plugin_count()

  • mysqlnd_plugin_get_plugin_connection_data()

  • mysqlnd_plugin_get_plugin_result_data()

  • mysqlnd_plugin_get_plugin_stmt_data()

  • mysqlnd_plugin_get_plugin_net_data()

  • mysqlnd_plugin_get_plugin_protocol_data()

  • mysqlnd_conn_get_methods()

  • mysqlnd_result_get_methods()

  • mysqlnd_result_meta_get_methods()

  • mysqlnd_stmt_get_methods()

  • mysqlnd_net_get_methods()

  • mysqlnd_protocol_get_methods()

There is no formal definition of what a plugin is and how a plugin mechanism works.

Components often found in plugins mechanisms are:

  • A plugin manager

  • A plugin API

  • Application services (or modules)

  • Application service APIs (or module APIs)

The mysqlnd plugin concept employs these features, and additionally enjoys an open architecture.

No Restrictions

A plugin has full access to the inner workings of mysqlnd. There are no security limits or restrictions. Everything can be overwritten to implement friendly or hostile algorithms. It is recommended you only deploy plugins from a trusted source.

As discussed previously, plugins can use pointers freely. These pointers are not restricted in any way, and can point into another plugin's data. Simple offset arithmetic can be used to read another plugin's data.

It is recommended that you write cooperative plugins, and that you always call the parent method. The plugins should always cooperate with mysqlnd itself.

Issues: an example of chaining and cooperation
Extension mysqlnd.query() pointer call stack if calling parent
ext/mysqlnd mysqlnd.query() mysqlnd.query
ext/mysqlnd_cache mysqlnd_cache.query()
  1. mysqlnd_cache.query()

  2. mysqlnd.query

ext/mysqlnd_monitor mysqlnd_monitor.query()
  1. mysqlnd_monitor.query()

  2. mysqlnd_cache.query()

  3. mysqlnd.query

In this scenario, a cache (ext/mysqlnd_cache) and a monitor (ext/mysqlnd_monitor) plugin are loaded. Both subclass Connection::query(). Plugin registration happens at MINIT using the logic shown previously. PHP calls extensions in alphabetical order by default. Plugins are not aware of each other and do not set extension dependencies.

By default the plugins call the parent implementation of the query method in their derived version of the method.

PHP Extension Recap

This is a recap of what happens when using an example plugin, ext/mysqlnd_plugin, which exposes the mysqlnd C plugin API to PHP:

  • Any PHP MySQL application tries to establish a connection to 192.168.2.29

  • The PHP application will either use ext/mysql, ext/mysqli or PDO_MYSQL. All three PHP MySQL extensions use mysqlnd to establish the connection to 192.168.2.29.

  • Mysqlnd calls its connect method, which has been subclassed by ext/mysqlnd_plugin.

  • ext/mysqlnd_plugin calls the userspace hook proxy::connect() registered by the user.

  • The userspace hook changes the connection host IP from 192.168.2.29 to 127.0.0.1 and returns the connection established by parent::connect().

  • ext/mysqlnd_plugin performs the equivalent of parent::connect(127.0.0.1) by calling the original mysqlnd method for establishing a connection.

  • ext/mysqlnd establishes a connection and returns to ext/mysqlnd_plugin. ext/mysqlnd_plugin returns as well.

  • Whatever PHP MySQL extension had been used by the application, it receives a connection to 127.0.0.1. The PHP MySQL extension itself returns to the PHP application. The circle is closed.

Getting started building a mysqlnd plugin

It is important to remember that a mysqlnd plugin is itself a PHP extension.

The following code shows the basic structure of the MINIT function that will be used in the typical mysqlnd plugin:

/* my_php_mysqlnd_plugin.c */

 static PHP_MINIT_FUNCTION(mysqlnd_plugin) {
  /* globals, ini entries, resources, classes */

  /* register mysqlnd plugin */
  mysqlnd_plugin_id = mysqlnd_plugin_register();

  conn_m = mysqlnd_get_conn_methods();
  memcpy(org_conn_m, conn_m,
    sizeof(struct st_mysqlnd_conn_methods));

  conn_m->query = MYSQLND_METHOD(mysqlnd_plugin_conn, query);
  conn_m->connect = MYSQLND_METHOD(mysqlnd_plugin_conn, connect);
}

/* my_mysqlnd_plugin.c */

 enum_func_status MYSQLND_METHOD(mysqlnd_plugin_conn, query)(/* ... */) {
  /* ... */
}
enum_func_status MYSQLND_METHOD(mysqlnd_plugin_conn, connect)(/* ... */) {
  /* ... */
}

Task analysis: from C to userspace

 class proxy extends mysqlnd_plugin_connection {
  public function connect($host, ...) { .. }
}
mysqlnd_plugin_set_conn_proxy(new proxy());

Process:

  1. PHP: user registers plugin callback

  2. PHP: user calls any PHP MySQL API to connect to MySQL

  3. C: ext/*mysql* calls mysqlnd method

  4. C: mysqlnd ends up in ext/mysqlnd_plugin

  5. C: ext/mysqlnd_plugin

    1. Calls userspace callback

    2. Or original mysqlnd method, if userspace callback not set

You need to carry out the following:

  1. Write a class "mysqlnd_plugin_connection" in C

  2. Accept and register proxy object through "mysqlnd_plugin_set_conn_proxy()"

  3. Call userspace proxy methods from C (optimization - zend_interfaces.h)

Userspace object methods can either be called using call_user_function() or you can operate at a level closer to the Zend Engine and use zend_call_method().

Optimization: calling methods from C using zend_call_method

The following code snippet shows the prototype for the zend_call_method function, taken from zend_interfaces.h.

 ZEND_API zval* zend_call_method(
  zval **object_pp, zend_class_entry *obj_ce,
  zend_function **fn_proxy, char *function_name,
  int function_name_len, zval **retval_ptr_ptr,
  int param_count, zval* arg1, zval* arg2 TSRMLS_DC
);

Zend API supports only two arguments. You may need more, for example:

 enum_func_status (*func_mysqlnd_conn__connect)(
  MYSQLND *conn, const char *host,
  const char * user, const char * passwd,
  unsigned int passwd_len, const char * db,
  unsigned int db_len, unsigned int port,
  const char * socket, unsigned int mysql_flags TSRMLS_DC
);

To get around this problem you will need to make a copy of zend_call_method() and add a facility for additional parameters. You can do this by creating a set of MY_ZEND_CALL_METHOD_WRAPPER macros.

Calling PHP userspace

This code snippet shows the optimized method for calling a userspace function from C:

/* my_mysqlnd_plugin.c */

MYSQLND_METHOD(my_conn_class,connect)(
  MYSQLND *conn, const char *host /* ... */ TSRMLS_DC) {
  enum_func_status ret = FAIL;
  zval * global_user_conn_proxy = fetch_userspace_proxy();
  if (global_user_conn_proxy) {
    /* call userspace proxy */
    ret = MY_ZEND_CALL_METHOD_WRAPPER(global_user_conn_proxy, host, /*...*/);
  } else {
    /* or original mysqlnd method = do nothing, be transparent */
    ret = org_methods.connect(conn, host, user, passwd,
          passwd_len, db, db_len, port,
          socket, mysql_flags TSRMLS_CC);
  }
  return ret;
}

Calling userspace: simple arguments

/* my_mysqlnd_plugin.c */

 MYSQLND_METHOD(my_conn_class,connect)(
  /* ... */, const char *host, /* ...*/) {
  /* ... */
  if (global_user_conn_proxy) {
    /* ... */
    zval* zv_host;
    MAKE_STD_ZVAL(zv_host);
    ZVAL_STRING(zv_host, host, 1);
    MY_ZEND_CALL_METHOD_WRAPPER(global_user_conn_proxy, zv_retval, zv_host /*, ...*/);
    zval_ptr_dtor(&zv_host);
    /* ... */
  }
  /* ... */
}

Calling userspace: structs as arguments

/* my_mysqlnd_plugin.c */

MYSQLND_METHOD(my_conn_class, connect)(
  MYSQLND *conn, /* ...*/) {
  /* ... */
  if (global_user_conn_proxy) {
    /* ... */
    zval* zv_conn;
    ZEND_REGISTER_RESOURCE(zv_conn, (void *)conn, le_mysqlnd_plugin_conn);
    MY_ZEND_CALL_METHOD_WRAPPER(global_user_conn_proxy, zv_retval, zv_conn, zv_host /*, ...*/);
    zval_ptr_dtor(&zv_conn);
    /* ... */
  }
  /* ... */
}

The first argument of many mysqlnd methods is a C "object". For example, the first argument of the connect() method is a pointer to MYSQLND. The struct MYSQLND represents a mysqlnd connection object.

The mysqlnd connection object pointer can be compared to a standard I/O file handle. Like a standard I/O file handle a mysqlnd connection object shall be linked to the userspace using the PHP resource variable type.

From C to userspace and back

 class proxy extends mysqlnd_plugin_connection {
  public function connect($conn, $host, ...) {
    /* "pre" hook */
    printf("Connecting to host = '%s'\n", $host);
    debug_print_backtrace();
    return parent::connect($conn);
  }

  public function query($conn, $query) {
    /* "post" hook */
    $ret = parent::query($conn, $query);
    printf("Query = '%s'\n", $query);
    return $ret;
  }
}
mysqlnd_plugin_set_conn_proxy(new proxy());

PHP users must be able to call the parent implementation of an overwritten method.

As a result of subclassing it is possible to refine only selected methods and you can choose to have "pre" or "post" hooks.

Buildin class: mysqlnd_plugin_connection::connect()

/*  my_mysqlnd_plugin_classes.c */

 PHP_METHOD("mysqlnd_plugin_connection", connect) {
  /* ... simplified! ... */
  zval* mysqlnd_rsrc;
  MYSQLND* conn;
  char* host; int host_len;
  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs",
    &mysqlnd_rsrc, &host, &host_len) == FAILURE) {
    RETURN_NULL();
  }
  ZEND_FETCH_RESOURCE(conn, MYSQLND* conn, &mysqlnd_rsrc, -1,
    "Mysqlnd Connection", le_mysqlnd_plugin_conn);
  if (PASS == org_methods.connect(conn, host, /* simplified! */ TSRMLS_CC))
    RETVAL_TRUE;
  else
    RETVAL_FALSE;
}

Mysqlnd 主从复制和负载均衡插件

目录

Mysql 主从复制和负载均衡插件 (mysqlnd_ms) 可以帮助我们很简单的支 持所有使用 mysqlnd 的 PHP MySQL 扩展。

自从 PHP 5.3.3 版本,MySQL native driver 以一个 C API 接口的方式存在。这个 C 插件, 可以通过 mysqlnd 完成对 MySQL 主从复制和负载均衡 的相关功能扩展。

从 PHP 5.3.0 以后,MySQL native driver 可以以 C 库的方式工作。它以插入的方式替代 MySQL Client 库 (libmysqlclient) 的作用。使用 mysqlnd 有几个好处: 不需要特别下载内容, 他已经被内置在 PHP 当中; 他基于 PHP 许可协议; 他会消耗更小的内存; 并且他包含很多新的 函数方法 (例如:异步查询).

Mysqlnd 插件 (例如 mysqlnd_ms) 都是从用户的使用要求中提炼出来. mysqlnd_ms 支持所有的 PHP 应用, 和所有的 MySQL PHP 扩展. 他并不改变现有的 APIs, 所以他可以很容易的在现有的 PHP 应用环境中使用.

Key Features

主要功能

  • 透明使用, 并且容易使用.

    • 支持所有的 PHP MySQL 扩展

    • 支持 SSL

    • 一致的 API 接口

    • 只需要很小的基于使用需要的方案设定

    • 被动连接,只有实际的 SQL 执行时,才会与 Master 和 Slaver 进行连接

    • 可选:从 Web request 的第一个写以后自动使用 Master, 降低可能的主从复制的延时影响

  • 可以在 MySQL Cluster 中使用

    • MySQL Replication: 实现读写分离, 插件主要为 MySQL Replication 编写

    • MySQL Cluster: 可以禁用读写分离, 可以使用多个 Master

    • 第三方解决方案: 插件为 MySQL Replication 定制开发, 但是也可以适用于其他的 MySQL Cluster 解决方案

  • 读写分离策略

    • 自动检测 SELECT 语句

    • Supports SQL hints to overrule automatism.

    • 用户自定义

    • 可以被禁用,例如在使用同步 Cluster 时

  • 负载均衡策略

    • Round Robin: 针对每一个 slave 查询,使用不同的 slave,轮循方式

    • Random: 随机选择 slave

    • Random once (sticky): 随机选取一个 slave, 在这个页面的请求过程中, 都是用这个 slave

    • User-defined: 应用可以在 mysqlnd_ms 中注册一个 callback

    • 从 PHP 5.4.0 以后版本,事务可以通过事务控制的 API 调用进行处理。

    • Weighted load balancing: Slave 可以被分配不同的优先级, 例如; 可以让更多的查询在一个更好的设备上执行, 或者在一个更近的设备查询以降低延时影响

  • Global transaction ID

    • Client-side emulation. Makes manual master server failover and slave promotion easier with asynchronous clusters, such as MySQL Replication.

    • 支持 MySQL 5.6.5 以上版本内置的 GTID.

    • 在 Session 一致性策略下,可以通过 GTID 完成异步 slave 读取最新的数据。

    • Throttling: optionally, the plugin can wait for a slave to become "synchronous" before continuing.

  • 服务和一致性级别

    • 应用可以在连接中选择:最终、session 和强一致性服务级别。最合适的通讯节点 将自动进行选择。

    • 最终一致性时,MySQL 主从同步的 slave 可以被本地 cache 替换,用于降低服务器负载。

  • 分区和共享

    • 数据库群组中的服务器,可以被定义到组中,利用 SQL hints 可以手动的指定在特定的组中进行查询。 组可以完成数据分区,或者完成数据热点的更新。

    • MySQL 主从同步过滤可以通过表过滤器支持。

限制

内置的读写分离机制非常基础, 任何一个以 SELECT 开头的查询, 都被认为是读操作, 从而发送给 slave 服务器. 所有其他的查询 (包括 SHOW) 都会被认为是写操作, 而被发送给 master 服务器. 内置的操作方法可以通过重写 SQL hints 改变, 或者使用一个用户定义的 callback 实现.

读写分离不能提供对于多查询的结构支持, 多查询结果会被认为是一个单一查询. 通过开头的字符串来决定如何执行这些查询. 例如, 如果使用 <span class="function">mysqli_multi_query 执行多查询 SELECT id FROM test; INSERT INTO test(id) VALUES (1) 将会被认为是一个查询操作, 而被发送给 slave 服务器, 以为他开头使用了 SELECT. 其中的 INSERT 结构,将不会被发送给 master 服务器.

Note:

应用必须知道连接切换的重要性, 他是负载均衡的墓地. 可以查看相关说明: connection pooling and switching, transaction handling, failover load balancingread-write splitting.

On the name

The shortcut mysqlnd_ms stands for mysqlnd master slave plugin. The name was chosen for a quick-and-dirty proof-of-concept. In the beginning the developers did not expect to continue using the code base.

快速入门与例子

目录

mysqlnd 是非常容易使用的 MySQL 主从复制负载均衡插件。 这里会给出用户使用的典型例子,并会提供开始使用的实用建议。

我们强烈建议您阅读相关在 Quickstart 中的相关章节。这里可以避免在理论、 概念和限制等方便的混淆。我们力劝您一定要阅读相关说明章节中的背景信息, 以避免在实际使用过程中遇到严重的问题。

焦点是将 PECL mysqlnd_ms 用于异步的 MySQL Cluster,也就是 MySQL replication (MySQL 主从复制)。一般来说,使用主从复制要比同步的 MySQL Cluster 要复杂,难用。所以这里能够为使用 MySQL Cluster 的用户提供更多的信息。

Setup

插件是一个 PHP 的扩展, 可以查看 installation instructions 学习如何安装 » PECL/mysqlnd_ms 扩展。

编译或配置 PHP MySQL 扩展 (API) (mysqliPDO_MYSQLmysql),也就是你打算使用的、支持 mysqlnd 的库。 PECL/mysqlnd_ms 是一个 mysqlnd 库的插件。使用任意 PHP MySQL 扩展时,要使用 mysqlnd 必须使用该插件。

然后,使用 mysqlnd_ms.enable 在 PHP 配置文件中装载和激活插件。

示例 #1 启用插件(php.ini)

mysqlnd_ms.enable=1
mysqlnd_ms.config_file=/path/to/mysqlnd_ms_plugin.ini

插件使用他自己的配置文件。使用 PHP 指令 mysqlnd_ms.config_file 定义插件配置文件的完整路径。 该文件必须能被 PHP 读取(比如 web 服务器的用户)。 请注意,从 1.4.0 版本开始配置文件变量使用 mysqlnd_ms.config_file, 以前的 mysqlnd_ms.ini_file 不再使用。 使用旧的、不再有效的指令是一个很常见的错误。

mysqlnd_ms.config_file 指定的目录中,创建保存插件的配置文件。

插件的 配置文件 基于 JSON 格式。 配置写在一个或者多个章节中。每个章节都包含一个名称,例如: myapp。 每个章节包含自己的配置信息。

一个章节的配置中,至少要包含 MySQL 主从复制中的 master 服务器和相关 slave 服务器。 每个章节只能使用一个 master 服务器。 目前还不能完全支持多 master(Multi-master)的设置。 master 用于设定 MySQL master 服务器的 hostname、port 或 socket。 而 MySQL slave 服务器信息使用 slave 来设定。

示例 #2 最基本的插件配置文件 (mysqlnd_ms_plugin.ini)

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost"
            }
        },
        "slave": [

        ]
    }
}

必须配置 MySQL slave 服务器列表,当然它也可以是空的列表。我们建议至少配置一个 slave 服务器。

服务器列表可以使用 匿名或者非匿名语法。 非匿名列表包含一个别名,例如 master_0 可用于上面的例子。 在这里,将使用更详细的非匿名语法。

示例 #3 建议最基本的插件配置文件 (mysqlnd_ms_plugin.ini)

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.2.27",
                "port": "3306"
            }
        }
    }
}

如果这里至少有两个服务器,插件可以负载均衡、切换连接。切换链接并不总是透明的,在某些具体条件下会导致问题。本参考中包含 连接池和切换事务处理故障转移 负载均衡读写分离。稍后在本指南中将具体描述更多潜在的陷阱。

应用需要处理连接切换过程中潜在的问题,配置一个 master 和至少一个 slave,这样就可以切换,因此能发现相关问题。

MySQL 主从同步并不需要你配置 master 和 slave。 为了测试的目的,你可以使用单个 MySQL 服务器,让插件认为是 master 和 slave 服务器,就像以下的设置。这样可以帮助你在连接切换中检测到很多潜在问题。 不过,这样的设置不容易发生因为主从同步延迟而导致的问题。

示例 #4 使用一个服务器同时作为 master 和 slave(仅用于测试!)

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "127.0.0.1",
                "port": "3306"
            }
        }
    }
}

插件将尝试通知你不合理的配置. 从 1.5.0 版本开始, 下列情况它抛出一个 PHP warning, 配置文件不可读; 空配置或者 JSON 配置语法错误. 通过 PHP 本身的配置,可能这些报警信息 会被放置在某些错误 LOG 文件当中。在验证完毕后,通过配置文件中有效的章节,连接会被建立。 设置 mysqlnd_ms.force_config_usage 可以帮助你进行 DEBUG。可以参考 配置文件 DEBUG 说明.

Running statements

这个插件可以配合 (mysqli, mysql, 和 PDO_MYSQL) 使用, 他们都是基于 mysqlnd library 工作的。 PECL/mysqlnd_ms 插件是 mysqlnd library 的一部分, 他并不改变这些扩展的 API 或者行为。

当 MySQL 链接打开的时候,插件会在配置文件中根据章节设定匹配 host 参数。 例如,插件配置文件中指定 myapp,那么可以使用 myapp 作为 host 打开 MySQL 链接。

示例 #1 插件指定的配置文件 (mysqlnd_ms_plugin.ini)

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.2.27",
                "port": "3306"
            }
        }
    }
}

示例 #2 开启一个负载均衡链接

<?php
/* 根据配置针对 myapp 开启一个负载均衡的链接 */
$mysqli = new mysqli("myapp", "username", "password", "database");
$pdo = new PDO('mysql:host=myapp;dbname=database', 'username', 'password');
$mysql = mysql_connect("myapp", "username", "password");
?>

上面的连接范例是负载均衡方式的。插件将发送只读查询给 192.168.2.27 端口 3306。其他的所有查询,将发送给 localhost 指定的 master 服务器。在 Linux 设备中, /tmp/mysql.sock 指定了本机的 MySQL 服务;在 Windows 系统中将使用默认的 TCP/IP 通讯。 插件将使用 usernamepassword 连接任何一个 在 myapp 章节中指定的数据库。在连接以后,将选择 database 设定的数据库作为当前操作数据库。

username, password 和默认数据库将在所有设定的数据库中做统一设定。 换句话说,就是所有的数据库必须使用同样的用户名口令登录。 从 1.1.0 版本以后,这个限制将不再存在,可以针对任何一个服务器通过 usernamepassword 进行登录鉴权设定。

插件在不改变查询结构的基础上,提供 读写分离。 下面的范例假定 master 和 slave 之间并没有很大的延迟。

示例 #3 Executing statements

<?php
/* myapp 负载均衡设定 */
$mysqli = new mysqli("myapp", "username", "password", "database");
if (mysqli_connect_errno())
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* 查询将在 master 上运行 */
if (!$mysqli->query("DROP TABLE IF EXISTS test")) {
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}
if (!$mysqli->query("CREATE TABLE test(id INT)")) {
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}
if (!$mysqli->query("INSERT INTO test(id) VALUES (1)")) {
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}

/* 只读查询将在 slave 上运行 */
if (!($res = $mysqli->query("SELECT id FROM test")) {
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
} else {
 $row = $res->fetch_assoc();
 $res->close();
 printf("Slave returns id = '%s'\n", $row['id'];
}
$mysqli->close();
?>

以上例程的输出类似于:

Slave returns id = '1'

连接状态

插件改变了 PHP MySQL 连接的控制,新建连接会从一个连接池中获取,用于替代 client-server 的单一连接方式。连接池包含一组 master 连接,和可选数目的 slave 连接。

连接池中的每一个连接都有自己的状态,例如:SQL 用户变量、临时表、事物状态。 所有的链接状态可以参考 连接池与切换 说明。 如果插件决定要为负载均衡切换连接,应用可能得到一个不同状态的链接。 应用必须能够处理这些问题。

示例 #1 配置了一个 master 和一个 slave 的插件

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.2.27",
                "port": "3306"
            }
        }
    }
}

示例 #2 陷阱:连接状态和 SQL 用户变量

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* 链接 1:绑定 SQL 用户变量,因为没有 SELECT 所以在 master 上执行 */
if (!$mysqli->query("SET @myrole='master'")) {
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}

/* 连接 2:因为有 SELECT 所以在 slave 上执行 */
if (!($res = $mysqli->query("SELECT @myrole AS _role"))) {
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
} else {
 $row = $res->fetch_assoc();
 $res->close();
 printf("@myrole = '%s'\n", $row['_role']);
}
$mysqli->close();
?>

以上例程会输出:

@myrole = ''

范例打开了负载均衡连接,并且执行两个查询。 第一个查询 SET @myrole='master' 没有以 SELECT 开头。然而并不能识别这是一个应该在 slave 中执行的查询,所以他被在 master 中执行。 所以这个变量被绑定在 master 连接中,master 连接设定被改变了。

然后执行 SELECT @myrole AS _role 查询,差将将其识别为只读查询, 并且发送给 slave 服务器。这样这个查询不会获得任何已经设定的 SQL 用户变量。 这个变量被设定在了第一次使用的 master 连接上面。所以范例将打印 @myrole = ''

这是开发人员必须注意的问题,插件并不会监控所有连接的变化情况。 若要监控所有的变化,将消耗大量的 CPU 资源。

当然这种陷阱,可以通过 SQL hints 解决。

SQL Hints (SQL 优化器)

SQL 优化器可以强行指定连接池中特定的链接。可以给定插件一个优化器去使用特定的服务器连接, 这样可以解决由于链接切换引起的链接状态变化问题。

SQL hints 是基于 SQL 语句的。因为 SQL 注释会被 SQL 执行器忽略, 他并不会妨碍 MySQL 服务器、MySQL proxy 或者任何防火墙的工作。

插件支持 SQL hints,MYSQLND_MS_MASTER_SWITCH hints 可以指定语句在 master 上运行,MYSQLND_MS_SLAVE_SWITCH 可以指定在 slave 上运行,MYSQLND_MS_LAST_USED_SWITCH 可以指定语句在上一条语句执行的 slave 上运行。

插件会扫描语句的内容,查询是否有 SQL hints。他只能在语句的开头被识别。

示例 #1 配置一个 master 和一个 slave 的插件

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.2.27",
                "port": "3306"
            }
        }
    }
}

示例 #2 SQL hints 禁止连接切换

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (mysqli_connect_errno())
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* 连接 1:设置一个 SQL 用户变量,没有 SELECT 所以运行在 master 上 */
if (!$mysqli->query("SET @myrole='master'")) {
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}

/* 连接 1:因为指定了 SQL hint */
if (!($res = $mysqli->query(sprintf("/*%s*/SELECT @myrole AS _role", MYSQLND_MS_LAST_USED_SWITCH)))) {
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
} else {
 $row = $res->fetch_assoc();
 $res->close();
 printf("@myrole = '%s'\n", $row['_role']);
}
$mysqli->close();
?>

以上例程会输出:

@myrole = 'master'

上面的范例使用 MYSQLND_MS_LASTER_USED_SWITCH 来防止在 master 和 slave 之间进行切换,即使运行了 SELECT 开头的语句。

SQL hints 也可以用于在 master 上运行 SELECT 语句。 这经常发生于 slave 中的数据落后于 master,但是希望获取当前数据的时候。

在 1.2.0 版本中,引入了服务级别的概念,用于处理即时数据获取的问题。 使用服务级别,可以降低对这个问题的关注,替代 SQL hints 的使用。 可以在服务级别和一致性的章节中找到更多的说明。

示例 #3 与同步延迟斗争

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* Force use of master, master has always fresh and current data */
if (!$mysqli->query(sprintf("/*%s*/SELECT critical_data FROM important_table", MYSQLND_MS_MASTER_SWITCH))) {
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}
?>

在使用中,slave 中应该有同样的表单。当没有给定 SQL hints 的时候,插件在发送 CREATE INSERT 语句到 master 服务器。 可以通过设定 MYSQLND_MS_SLAVE_SWITCH 来让这些语句在 slave 中运行。例如建立一个临时表单:

示例 #4 Table creation on a slave

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* 强迫在 slave 运行 */
if (!$mysqli->query(sprintf("/*%s*/CREATE TABLE slave_reporting(id INT)", MYSQLND_MS_SLAVE_SWITCH))) {
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}
/* 使用刚刚使用的 slave 连接 */
if (!$mysqli->query(sprintf("/*%s*/INSERT INTO slave_reporting(id) VALUES (1), (2), (3)", MYSQLND_MS_LAST_USED_SWITCH))) {
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}
/* 不使用 MYSQLND_MS_SLAVE_SWITCH 将会切换到另外一台 slave */
if ($res = $mysqli->query(sprintf("/*%s*/SELECT COUNT(*) AS _num FROM slave_reporting", MYSQLND_MS_LAST_USED_SWITCH))) {
  $row = $res->fetch_assoc();
  $res->close();
  printf("There are %d rows in the table 'slave_reporting'", $row['_num']);
} else {
  printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}
$mysqli->close();
?>

SQL hint MYSQLND_MS_LAST_USED 禁止切换连接, 他将使用上一次使用的链接。

事务

当前版本的插件并不是事务安全的,因为他并没有识别全部的事务操作。 SQL 事务单元是在单一服务器中运行的。插件并不能有效的知道事务单元 何时开始,何时终止。所以,在事务单元中,可能数据库连接会被切换。

如果应用没有设定事务单元编辑,那么没有任何 MySQL 负载均衡能够检测他。

可以通过 SQL hints 来解除这个限制。可以选择性的调用事务 API 进行监控, 然后嗲用 API 执行控制事务。下面给出范例:

示例 #1 配置一个 master 和一个 slave 的插件

[myapp]
{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.2.27",
                "port": "3306"
            }
        }
    }
}

示例 #2 在事务中使用 SQL hints

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* 不是 SELECT 开头,所以使用 master */
if (!$mysqli->query("START TRANSACTION")) {
 /* Please use better error handling in your code */
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}

/* 禁止连接切换*/
if (!$mysqli->query(sprintf("/*%s*/INSERT INTO test(id) VALUES (1)", MYSQLND_MS_LAST_USED_SWITCH)))) {
 /* Please do proper ROLLBACK in your code, don't just die */
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}
if ($res = $mysqli->query(sprintf("/*%s*/SELECT COUNT(*) AS _num FROM test", MYSQLND_MS_LAST_USED_SWITCH)))) {
  $row = $res->fetch_assoc();
  $res->close();
  if ($row['_num'] > 1000) {
   if (!$mysqli->query(sprintf("/*%s*/INSERT INTO events(task) VALUES ('cleanup')", MYSQLND_MS_LAST_USED_SWITCH)))) {
     die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
   }
  }
} else {
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}
if (!$mysqli->query(sprintf("/*%s*/UPDATE log SET last_update = NOW()", MYSQLND_MS_LAST_USED_SWITCH)))) {
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}
if (!$mysqli->query(sprintf("/*%s*/COMMIT", MYSQLND_MS_LAST_USED_SWITCH)))) {
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}

$mysqli->close();
?>

自从 PHP 5.4.0 版本开始,mysqlnd library 允许插件监控 autocommit 模式下的状态,例如调用 SET AUTOCOMMIT=0 这样的语句,这将让插件开始关心事务处理。这样你就可以不用使用 SQl hints。

从 PHP 5.4.0 版本开始,调用 API autocommit 模式,插件设定中有 trx_stickiness=master, 那么插件将在事务中自动禁止负载均衡和连接切换。在 autocommit 禁用的配置当中, 插件将在事务过程中将所有的语句发送给 master,禁用负载均衡。当 autocommit 重新启用以后,插件将重新开始负载均衡所有的语句。

在 PHP 5.5.0 和 PECL/mysqlnd_ms 1.5.0 版本后,这种检查将不仅仅检查 mysqli_autocommit 还会检查 <span class="function">mysql_commit 和 <span class="function">mysql_rollback。

示例 #3 事务相关负载均衡下的 trx_stickiness 设置

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "127.0.0.1",
                "port": "3306"
            }
        },
        "trx_stickiness": "master"
    }
}

示例 #4 Transaction aware

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* 禁用 autocommit,插件将所有语句发送给 master */
$mysqli->autocommit(FALSE);

if (!$mysqli->query("INSERT INTO test(id) VALUES (1)")) {
 /* Please do proper ROLLBACK in your code, don't just die */
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}
if ($res = $mysqli->query("SELECT COUNT(*) AS _num FROM test")) {
  $row = $res->fetch_assoc();
  $res->close();
  if ($row['_num'] > 1000) {
   if (!$mysqli->query("INSERT INTO events(task) VALUES ('cleanup')")) {
     die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
   }
  }
} else {
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}
if (!$mysqli->query("UPDATE log SET last_update = NOW()")) {
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}
if (!$mysqli->commit()) {
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}

/* 插件判定事务终止,重新启用负载均衡 */
$mysqli->autocommit(TRUE);
$mysqli->close();
?>

Note: 版本需求

trx_stickiness=master 参数需要 PHP 5.4.0 以上版本。

可以参考相关限制在 transaction handling 章节中。

XA/Distributed Transactions

Note: Version requirement

XA related functions have been introduced in PECL mysqlnd_ms version 1.6.0-alpha.

Note: Experimental

The feature is currently under development. There may be issues and/or feature limitations. Do not use in production environments.

XA transactions are a standardized method for executing transactions across multiple resources. Those resources can be databases or other transactional systems. The MySQL server supports XA SQL statements which allows users to carry out a distributed SQL transaction that spawns multiple database servers or any kind as long as they support the SQL statements too. In such a scenario it is in the responsibility of the user to coordinate the participating servers.

PECL/mysqlnd_ms can act as a transaction coordinator for a global (distributed, XA) transaction carried out on MySQL servers only. As a transaction coordinator, the plugin tracks all servers involved in a global transaction and transparently issues appropriate SQL statements on the participants. The global transactions are controlled with <span class="function">mysqlnd_ms_xa_begin, <span class="function">mysqlnd_ms_xa_commit and <span class="function">mysqlnd_ms_xa_rollback. SQL details are mostly hidden from the application as is the need to track and coordinate participants.

示例 #1 General pattern for XA transactions

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* start a global transaction */
$gtrid_id = "12345";
if (!mysqlnd_ms_xa_begin($mysqli, $gtrid_id)) {
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}

/* run queries as usual: XA BEGIN will be injected upon running a query */
if (!$mysqli->query("INSERT INTO orders(order_id, item) VALUES (1, 'christmas tree, 1.8m')")) {
   /* Either INSERT failed or the injected XA BEGIN failed */
  if ('XA' == substr($mysqli->sqlstate, 0, 2)) {
    printf("Global transaction/XA related failure, [%d] %s\n", $mysqli->errno, $mysqli->error);
  } else {
    printf("INSERT failed, [%d] %s\n", $mysqli->errno, $mysqli->error);
  }
  /* rollback global transaction */
  mysqlnd_ms_xa_rollback($mysqli, $xid);
  die("Stopping.");
}

/* continue carrying out queries on other servers, e.g. other shards */

/* commit the global transaction */
if (!mysqlnd_ms_xa_commit($mysqli, $xa_id)) {
  printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}
?>

Unlike with local transactions, which are carried out on a single server, XA transactions have an identifier (xid) associated with them. The XA transaction identifier is composed of a global transaction identifier (gtrid), a branch qualifier (bqual) a format identifier (formatID). Only the global transaction identifier can and must be given when calling any of the plugins XA functions.

Once a global transaction has been started, the plugin begins tracking servers until the global transaction ends. When a server is picked for query execution, the plugin injects the SQL statement XA BEGIN prior to executing the actual SQL statement on the server. XA BEGIN makes the server participate in the global transaction. If the injected SQL statement fails, the plugin will report the issue in reply to the query execution function that was used. In the above example, $mysqli->query("INSERT INTO orders(order_id, item) VALUES (1, 'christmas tree, 1.8m')") would indicate such an error. You may want to check the errors SQL state code to determine whether the actual query (here: INSERT) has failed or the error is related to the global transaction. It is up to you to ignore the failure to start the global transaction on a server and continue execution without having the server participate in the global transaction.

示例 #2 Local and global transactions are mutually exclusive

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* start a local transaction */
if (!$mysqli->begin_transaction())
  die(sprintf("[%d/%s] %s\n", $mysqli->errno, $mysqli->sqlstate, $mysqli->error));

/* cannot start global transaction now - must end local transaction first */
$gtrid_id = "12345";
if (!mysqlnd_ms_xa_begin($mysqli, $gtrid_id)) {
  die(sprintf("[%d/%s] %s\n", $mysqli->errno, $mysqli->sqlstate, $mysqli->error));
}
?>

以上例程会输出:

Warning: mysqlnd_ms_xa_begin(): (mysqlnd_ms) Some work is done outside global transaction. You must end the active local transaction first in ... on line ...
[1400/XAE09] (mysqlnd_ms) Some work is done outside global transaction. You must end the active local transaction first

A global transaction cannot be started when a local transaction is active. The plugin tries to detect this situation as early as possible, that is when mysqlnd_ms_xa_begin is called. If using API calls only to control transactions, the plugin will know that a local transaction is open and return an error for <span class="function">mysqlnd_ms_xa_begin. However, note the plugins limitations on detecting transaction boundaries.. In the worst case, if using direct SQL for local transactions (BEGIN, COMMIT, ...), it may happen that an error is delayed until some SQL is executed on a server.

To end a global transaction invoke <span class="function">mysqlnd_ms_xa_commit or <span class="function">mysqlnd_ms_xa_rollback. When a global transaction is ended all participants must be informed of the end. Therefore, PECL/mysqlnd_ms transparently issues appropriate XA related SQL statements on some or all of them. Any failure during this phase will cause an implicit rollback. The XA related API is intentionally kept simple here. A more complex API that gave more control would bare few, if any, advantages over a user implementation that issues all lower level XA SQL statements itself.

XA transactions use the two-phase commit protocol. The two-phase commit protocol is a blocking protocol. There are cases when no progress can be made, not even when using timeouts. Transaction coordinators should survive their own failure, be able to detect blockades and break ties. PECL/mysqlnd_ms takes the role of a transaction coordinator and can be configured to survive its own crash to avoid issues with blocked MySQL servers. Therefore, the plugin can and should be configured to use a persistent and crash-safe state to allow garbage collection of unfinished, aborted global transactions. A global transaction can be aborted in an open state if either the plugin fails (crashes) or a connection from the plugin to a global transaction participant fails.

示例 #3 Transaction coordinator state store

{
    "myapp": {
        "xa": {
            "state_store": {
                "participant_localhost_ip": "192.168.2.12",
                "mysql": {
                    "host": "192.168.2.13",
                    "user": "root",
                    "password": "",
                    "db": "test",
                    "port": "3312",
                    "socket": null
                }
            }
        },
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.2.14",
                "port": "3306"
            }
        }
    }
}

Currently, PECL/mysqlnd_ms supports only using MySQL database tables as a state store. The SQL definitions of the tables are given in the plugin configuration section. Please, make sure to use a transactional and crash-safe storage engine for the tables, such as InnoDB. InnoDB is the default table engine in recent versions of the MySQL server. Make also sure the database server itself is higly available.

If a state store has been configured, the plugin can perform a garbage collection. During garbage collection it may be necessary to connect to a participant of a failed global transaction. Thus, the state store holds a list of participants and, among others, their host names. If the garbage collection is run on another host but the one that has written a participant entry with the host name localhost, then localhost resolves to different machines. There are two solutions to the problem. Either you do not configure any servers with the host name localhost but configure an IP address (and port) or, you hint the garbage collection. In the above example, localhost is used for master_0, hence it may not resolve to the correct host during garbage collection. However, participant_localhost_ip is also set to hint the garbage collection that localhost stands for the IP 192.168.2.12.

服务级别和一致性

Note: 版本需求

服务级别是从 1.2.0-alpha版本引入的,<span class="function">mysqlnd_ms_set_qos 从 PHP 5.4.0 版本开始可以使用。

不同类型的 MySQL 群组提供了,不同的服务和数据一致性级别。异步的 MySQL 主从同步 提供最终的数据一致性,一个读操作是否能够得到当前的数据、状态,一类与 slave 是否已经从 master 获取了最后的更新。

使用 MySQL 主从同步依赖于网络的有效性,最终会获得数据的一致性。然而, 状态数据是不能同步的。这样,只有指定的 slave 或者 master 连接才能得到所有内容。

从 1.2.0 版本开始,插件能够自动的进行 MySQL 主从同步的节点,来完成 session 一致性 或者完成很强的一致性要求。session 一致性是指一个客户端可以读取他的写入内容, 其他客户端可能不能看到他的写入内容。很强的一致性要求是指所有客户端都能够看到 其他所有客户端的写入内容。

示例 #1 session 一致性:读取写入内容

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "127.0.0.1",
                "port": "3306"
            }
        }
    }
}

示例 #2 Requesting session consistency

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* 使用 master 完成读写分离 */
if (!$mysqli->query("INSERT INTO orders(order_id, item) VALUES (1, 'christmas tree, 1.8m')")) {
   /* Please use better error handling in your code */
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}

/* 要求 session 一致性,读取写入内容 */
if (!mysqlnd_ms_set_qos($mysqli, MYSQLND_MS_QOS_CONSISTENCY_SESSION))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

/* 插件选择一个改变数据的节点,这里是 master */
if (!$res = $mysqli->query("SELECT item FROM orders WHERE order_id = 1"))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

var_dump($res->fetch_assoc());

/* 返回到最终数据一致性状态,允许陈旧数据 */
if (!mysqlnd_ms_set_qos($mysqli, MYSQLND_MS_QOS_CONSISTENCY_EVENTUAL))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

/* 插件选择任何一个 slaver 完成允许陈旧数据的读取 */
if (!$res = $mysqli->query("SELECT item, price FROM specials"))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
?>

服务级别可以被写在插件的配置文件中,也可以在运行时使用 <span class="function">mysqlnd_ms_set_qos 设定。 在范例中,使用这个函数强制 session 一致性,直到再次通知改变。 orders 表单中的 SELECT 语句在前面写入使用的 连接中执行。读写分离逻辑被服务级别策略改变。

在从 orders 表单读取数据以后,恢复到默认的服务级别 (最终数据一致性)。 这时,语句执行选择的服务器将不再被限制,因而在 specials 表单上做的 SELECT 查询将在一个 slave 服务器中进行。

一个新的替代 SQL hint的功能,master_on_write 配置设定。 在绝大部分情况下 mysqlnd_ms_set_qos 更容易使用, 使用它移植性更好。

示例 #3 Maximum age/slave lag

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "127.0.0.1",
                "port": "3306"
            }
        },
        "failover" : "master"
    }
}

示例 #4 限制 slave 延迟

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* 若 slave 延迟不超过 4 秒,则从 Slave 读取 */
$ret = mysqlnd_ms_set_qos($mysqli,
         MYSQLND_MS_QOS_CONSISTENCY_EVENTUAL,
         MYSQLND_MS_QOS_OPTION_AGE, 4);

if (!$ret)
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

/* 选择一个 slave,他可能没有改变 */
if (!$res = $mysqli->query("SELECT item, price FROM daytrade"))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));


/* 恢复默认状态,使用所有的 slave 和 master */
if (!mysqlnd_ms_set_qos($mysqli, MYSQLND_MS_QOS_CONSISTENCY_EVENTUAL))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
?>

最终一致性服务级别可以使用一个可选的参数设定最大允许的延迟,用于选择 slave。 如果设定这个值,插件会检查所有 slave 的 SHOW SLAVE STATUS。 在范例中,只有满足 Slave_IO_Running=Yes, Slave_SQL_Running=YesSeconds_Behind_Master \<= 4 的 slave 会被执行语句 SELECT item, price FROM daytrade

在应用运行时,会透明的执行 SHOW SLAVE STATUS 命令。 任何错误会以 warning 的方式报警,但是错误信息不会被保存在连接中。 即使所有的 SHOW SLAVE STATUS 都失败了,用户的执行请求也不会被终止, 给定的 master 作为最后的选择。然而应用不需要做任何调整。

Note: 耗时和缓慢的操作

在任何程序的开始,对所有的 slave 进行 SHOW SLAVE STATUS 查询,是一个非常耗时和缓慢的操作。不要经常这样操作。MySQL 主从同步集群并没有 提供一个客户端从一个中心控制器获取备选方案的能力。 然而,没有更多有效的方式获取 slave 延迟。

请注意,关于 SHOW SLAVE STATUS 的各种限制和参数说明, 请参考 MySQl 的参考手册。

若要禁止插件,在没有找到满足延迟条件的 slave 时产生报警,需要在配置文件 当中设定 master 作为故障处理。如果没有 slave 满足条件,那么故障处理开始启动, 插件会使用 master 去执行语句。

如果没有 slave 满足条件,并且没有启动故障处理,插件将会报警。 这时,语句不会被执行,并且错误信息会被写入连接当中。

示例 #5 不设置故障处理

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "127.0.0.1",
                "port": "3306"
            }
        }
    }
}

示例 #6 No slave within time limit

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* 若 slave 延迟不超过 4 秒,则从 slave 执行 */
$ret = mysqlnd_ms_set_qos($mysqli,
         MYSQLND_MS_QOS_CONSISTENCY_EVENTUAL,
         MYSQLND_MS_QOS_OPTION_AGE, 4);

if (!$ret)
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

/* Plugin picks any slave, which may or may not have the changes */
if (!$res = $mysqli->query("SELECT item, price FROM daytrade"))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));


/* Back to default: use of all slaves and masters permitted */
if (!mysqlnd_ms_set_qos($mysqli, MYSQLND_MS_QOS_CONSISTENCY_EVENTUAL))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
?>

以上例程会输出:

PHP Warning:  mysqli::query(): (mysqlnd_ms) Couldn't find the appropriate slave connection. 0 slaves to choose from. Something is wrong in %s on line %d
PHP Warning:  mysqli::query(): (mysqlnd_ms) No connection selected by the last filter in %s on line %d
[2000] (mysqlnd_ms) No connection selected by the last filter

Global transaction IDs (GTID)

Note: 版本需求

从 1.2.0-alpha 版本开始客户端 GTID 可以使用,这个功能并不需要在同步集群中使用, 例如 MySQL Cluster。他用于异步集群,例如 MySQL 主从同步。

从 MySQL 5.6.5-m8 版本开始,MySQL 使用内置的 GTID,这需要 1.3.0-alpha 以后版本支持。

PECL/mysqlnd_ms 可以使用自己的 GTID 仿真,或者使用 MySQL 内置的 GTID。无论使用哪种方式, 对于使用服务级别来说都是一样的。他们的区别,在 concepts section 进行说明。

这里先使用插件内部的 GTID 模拟来展示如何使用服务端的副本。

概念和客户端模拟

GTID 是 slave 需要同步的 table 在 master 上基于这个 table 的一个计数器,每当事务提交他都会增加。 这个计数器有两个作用,如果 master 产生故障,他帮助数据库管理员确定使用最新的 slave 来 恢复新的 master。最新的 slave 就是那个数值最高的。应用可以使用 GTID 查询某一次写入, 是否已经在 slave 被同步。

插件可以在每次提交事务的时候,增加 GTID。当然这个 GTID 也可以让应用判断写操作是否同步。 这样就可以实现在 session 一致性服务级别中,不一定从 master 读取数据,也可以从已经同步 的 slave 中获取数据,从而减轻 master 的读负载。

客户端 GTID 模拟有一些限制,可以参考 concepts section 说明。在生产换金钟使用前,请细致全面的理解他的工作原理和概念。相关背景的支持, 不在本参考中进行说明。

首先在 master 建立一个计数器表,并且插入一条记录。插件并不会帮助你建立这个表, 数据库管理员需要帮助你操作。如果表不存在或者有问题,基于错误报告机制, 你可能得不到任何错误信息。

示例 #1 在 master 创建计数器表

CREATE TABLE `trx` (
  `trx_id` int(11) DEFAULT NULL,
  `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1
INSERT INTO `trx`(`trx_id`) VALUES (1);

在插件的配置文件中,需要在 global_transaction_id_injection 章节中设定 on_commit 参数。一定要确认在 UPDATE 中使用的表明是可达的,例如:使用上一步创建的表, test.trx 要比 trx 更合适。 这一点非常重要,因为不同的数据库连接,可能的默认数据库选择并不相同。 并且确认,使用连接的用户,有权限对这个表执行 UPDATE 命令。

当 GTID 更新时,打开错误报告。

示例 #2 Plugin config: SQL for client-side GTID injection

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "127.0.0.1",
                "port": "3306"
            }
        },
        "global_transaction_id_injection":{
            "on_commit":"UPDATE test.trx SET trx_id = trx_id + 1",
            "report_error":true
        }
    }
}

示例 #3 Transparent global transaction ID injection

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* auto commit mode, transaction on master, GTID must be incremented */
if (!$mysqli->query("DROP TABLE IF EXISTS test"))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

/* auto commit mode, transaction on master, GTID must be incremented */
if (!$mysqli->query("CREATE TABLE test(id INT)"))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

/* auto commit mode, transaction on master, GTID must be incremented */
if (!$mysqli->query("INSERT INTO test(id) VALUES (1)"))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

/* auto commit mode, read on slave, no increment */
if (!($res = $mysqli->query("SELECT id FROM test")))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

var_dump($res->fetch_assoc());
?>

以上例程会输出:

array(1) {
  ["id"]=>
  string(1) "1"
}

上面的范例运行 3 条语句在 master 上,他们都是在 autocommit 下执行,这样会引起 3 次 GTID 的增加。每次插件都会在执行语句以前,根据配置中的 UPDATE 设定 增加 GTID。

第四条语句,因为是 SELECT 语句,并不会在 master 上执行, 所以不会引发 master 增加 GTID。

Note: 基于 SQL 的 GTID 如何有效率的工作

在客户端通过 GTID 模拟在每个 SQL 执行的时候处理是很没有效率的做法。 这样做,是为了能够清楚的说明情况,而不是为了执行效率,不要在实际的 生产环境中这样使用。可以在本文中找到更有效率的做法。

示例 #4 Plugin config: SQL for fetching GTID

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "127.0.0.1",
                "port": "3306"
            }
        },
        "global_transaction_id_injection":{
            "on_commit":"UPDATE test.trx SET trx_id = trx_id + 1",
            "fetch_last_gtid" : "SELECT MAX(trx_id) FROM test.trx",
            "report_error":true
        }
    }
}

示例 #5 Obtaining GTID after injection

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* auto commit mode, transaction on master, GTID must be incremented */
if (!$mysqli->query("DROP TABLE IF EXISTS test"))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

printf("GTID after transaction %s\n", mysqlnd_ms_get_last_gtid($mysqli));

/* auto commit mode, transaction on master, GTID must be incremented */
if (!$mysqli->query("CREATE TABLE test(id INT)"))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

printf("GTID after transaction %s\n", mysqlnd_ms_get_last_gtid($mysqli));
?>

以上例程会输出:

GTID after transaction 7
GTID after transaction 8

应用可以通过插件获取最后一次写操作产生的 GTID。函数<span class="function">mysqlnd_ms_get-last-gtid 通过在配置文件中 global_transaction_id_injection 章节中 定义的 fetch_last-gtid 方法,返回最后一次 写操作产生的 GTID。函数应该在 GTID 增加后调用。

不建议应用运行自己运行哪些可能产生风险的 SQL 语句,从而增加 GTID。并且,使用函数 可以轻松的将查询 GTID 迁移到其他应用中。例如,使用任何 MySQL 内置的 GTID。

这里展现了一个 SQL 语句获得了他的 GTID 或者比实际执行得到的 GTID 更大的数据。 在 SELECT 和 查询 GTID 之间,可能有其他的客户端执行 SQL 语句,从而增加了 GTID,所以获得的 GTID 可能比实际数据大。

示例 #6 Plugin config: Checking for a certain GTID

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "127.0.0.1",
                "port": "3306"
            }
        },
        "global_transaction_id_injection":{
            "on_commit":"UPDATE test.trx SET trx_id = trx_id + 1",
            "fetch_last_gtid" : "SELECT MAX(trx_id) FROM test.trx",
            "check_for_gtid" : "SELECT trx_id FROM test.trx WHERE trx_id >= #GTID",
            "report_error":true
        }
    }
}

示例 #7 Session consistency service level and GTID combined

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* autocommit 模式下,在 master 执行,用于增加 GTID */
if (!$mysqli->query("DROP TABLE IF EXISTS test") ||
    !$mysqli->query("CREATE TABLE test(id INT)") ||
    !$mysqli->query("INSERT INTO test(id) VALUES (1)"))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

/* 获取最后一次写入的 GTID */
$gtid = mysqlnd_ms_get_last_gtid($mysqli);

/* Session 一致性,尝试从 slave 读取,而不只从 master 读取 */
if (false == mysqlnd_ms_set_qos($mysqli, MYSQLND_MS_QOS_CONSISTENCY_SESSION, MYSQLND_MS_QOS_OPTION_GTID, $gtid)) {
    die(sprintf("[006] [%d] %s\n", $mysqli->errno, $mysqli->error));
}

/* Either run on master or a slave which has replicated the INSERT */
if (!($res = $mysqli->query("SELECT id FROM test"))) {
    die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}

var_dump($res->fetch_assoc());
?>

通过 mysqlnd_ms_get_last_gtid 获取的 GTID 可以被用于 Session 一致性服务级别。通过 <span class="function">mysqlnd_ms_set_qos 设定 Session 一致性服务级别,他决定从哪里读取写入的数据。在范例中, 通过判断 INSERT 是否已经被同步,来决定 SELECT 从哪个服务器中读取数据,

插件检查配置中的所有 slave 服务器,通过查看 GTID 表中的值,判断是否 INSERT 已经被同步。检查的方法在 global_transaction_id_injection 章节中,使用 check_for_gtid 参数定义。 请注意,这是一种低效,浪费资源的方法。 在 master 的读取压力很大的时候,应用可以零星的采用这种方式,来降低读取压力。

使用服务器端的 GTID

自从 MySQL 5.6.5-m8 版本开始,MySQL 主从同步开始支持服务器端的 GTID。GTID 的 创建和增长由服务器控制,用户可以不再关心这些问题。这也就是说,不需要再添加任何 数据库表用于记录 GTID,也不用设置 on_commit 方法。客户端模拟 的 GTID 不再需要使用。

客户端可以顺畅使用 GTID 完成 Session 一致性服务,运算的方式与上面描述的 GTID 模拟 是一样的。不同的是 check_for_gtidfetch_last_gtid 还是需要进行配置。 请注意,MySQL 5.6.5-m8 是一个研发版本,具体执行细节在实际的运行版本对于这些功能可能有改变。

使用下面的配置,可以上上面讨论过的任何一个脚本,能够利用服务器端的 GTID 正常工作。 函数 <span class="function">mysqlnd_ms_get_last_gtid 和 <span class="function">mysqlnd_ms_set_qos 工作也一样正常。不同点在于, 服务器并不采用简单的顺序序列,而是采用一个包含服务器标识号和序列数字的字符串。 所以,用户并不能简单的通过 <span class="function">mysqlnd_ms_get_last_gtid 得到的顺序判断 GTID。 译者注:从 MySQL 5.6.9 版本开始 GTID_DONE 已经被 GTID_EXECUTED 替代,所以下面的 范例中,应该做相应变更。

示例 #8 使用 MySQL 5.6.5-m8 内置 GTID

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "127.0.0.1",
                "port": "3306"
            }
        },
        "global_transaction_id_injection":{
            "fetch_last_gtid" : "SELECT @@GLOBAL.GTID_DONE AS trx_id FROM DUAL",
            "check_for_gtid" : "SELECT GTID_SUBSET('#GTID', @@GLOBAL.GTID_DONE) AS trx_id FROM DUAL",
            "report_error":true
        }
    }
}

Cache integration

Note: 版本需求、依赖性和状态

可以从 concepts section 获取更多的内容。

数据库群组可以设定不同的一致性级别。从 1.2.0 版本,我们建议插件仅仅从群组节点选择上 考虑使用的一致性级别。例如,如果使用异步的 MySQL 主从同步,他采用群组的最终一致性, 建议在任何时间通过 <span class="function">mysqlnd_ms_set_quos 使用 Session 一致性。 这可以参考 服务级别与一致性

示例 #1 Recap: quality of service to request read your writes

/* 设定采用 Session 一致性 */
if (!mysqlnd_ms_set_qos($mysqli, MYSQLND_MS_QOS_CONSISTENCY_SESSION))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

假设插件使用最终一致性服务级别,而不采用其他更高要求的一致性策略。那么插件可能使用 通过 TTL 失效策略控制的缓存来替代从数据库节点读取数据。数据库节点和缓存都采用 最终一致性策略,他们可能保存的不是最新的数据。

通过本地缓存替代数据库操作,可以有效的提升性能,降低数据库压力。 如果其他客户端比创建这个缓存条目的客户端更频繁使用他,那么数据库的访问就被降低下来, 从而降低数据库压力。并且,由于本地缓存的速度快于数据库查询,那么整体计算性能就被提升。

示例 #2 Plugin config: no special entries for caching

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "127.0.0.1",
                "port": "3306"
            }
        },
    }
}

示例 #3 Caching a slave request

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

if (!$mysqli->query("DROP TABLE IF EXISTS test") ||
    !$mysqli->query("CREATE TABLE test(id INT)") ||
    !$mysqli->query("INSERT INTO test(id) VALUES (1)"))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

/* 确认允许最终一致性,并且设定缓存有效期 (TTL <= 60 seconds) */
if (false == mysqlnd_ms_set_qos($mysqli, MYSQLND_MS_QOS_CONSISTENCY_EVENTUAL, MYSQLND_MS_QOS_OPTION_CACHE, 60)) {
    die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}

/* 为了让范例工作,我们采用强制性的循环捕捉 slave 操作 */
$attempts = 0;
do {
  /* check if slave has the table */
  if ($res = $mysqli->query("SELECT id FROM test")) {
    break;
  } else if ($mysqli->errno) {
    die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
  }
  /* wait for slave to catch up */
  usleep(200000);
} while ($attempts++ < 10);

/* Query has been run on a slave, result is in the cache */
assert($res);
var_dump($res->fetch_assoc());

/* Served from cache */
$res = $mysqli->query("SELECT id FROM test");
?>

上面的范例说明如何使用缓存功能。通过 <span class="function">mysqlnd_ms_set_qos 设定最终一致性服务器级别,并且允许使用缓存。然后任何只读的操作都会被放入 缓存中,存活时间通过 mysqlnd_ms_set_qos 指定。

实际的 TTL 要比通过 mysqlnd_ms_set_qos 设定的要小,设定值 是他的最大值。插件会在 TTL 上扣除 slave 同步延迟,用于计算实际的 TTL。在范例中, 如果 slave 的同步延迟是 10 秒,TTL 的最大值是 60 秒,那么计算的 TTL 值是 50 秒。 TTL 的计算,对于每一个缓存条目是独立的。

示例 #4 Read your writes and caching combined

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

if (!$mysqli->query("DROP TABLE IF EXISTS test") ||
    !$mysqli->query("CREATE TABLE test(id INT)") ||
    !$mysqli->query("INSERT INTO test(id) VALUES (1)"))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

/* Explicitly allow eventual consistency and caching (TTL <= 60 seconds) */
if (false == mysqlnd_ms_set_qos($mysqli, MYSQLND_MS_QOS_CONSISTENCY_EVENTUAL, MYSQLND_MS_QOS_OPTION_CACHE, 60)) {
    die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}

/* To make this example work, we must wait for a slave to catch up. Brute force style. */
$attempts = 0;
do {
  /* check if slave has the table */
  if ($res = $mysqli->query("SELECT id FROM test")) {
    break;
  } else if ($mysqli->errno) {
    die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
  }
  /* wait for slave to catch up */
  usleep(200000);
} while ($attempts++ < 10);

assert($res);

/* Query has been run on a slave, result is in the cache */
var_dump($res->fetch_assoc());

/* Served from cache */
if (!($res = $mysqli->query("SELECT id FROM test")))
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
var_dump($res->fetch_assoc());

/* Update on master */
if (!$mysqli->query("UPDATE test SET id = 2"))
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

/* Read your writes */
if (false == mysqlnd_ms_set_qos($mysqli, MYSQLND_MS_QOS_CONSISTENCY_SESSION)) {
    die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}

/* Fetch latest data */
if (!($res = $mysqli->query("SELECT id FROM test")))
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
var_dump($res->fetch_assoc());
?>

服务设定可以随时改变,用于屏蔽缓存的使用。如果需要,你可以变更为 Session 一致性策略, 这时缓存将不会被使用,并且被更新为最新的数据结果。

故障转移

默认情况下,插件并不会在连接一个服务器失败的时候进行故障处理。这是为了防止 连接状态中的陷阱。 这里建议手动的对连接错误进行处理,你可以捕获这个错误,重新建立连接,执行的你的查询,如同下面展示的那样。

如果连接状态并不是由于你的操作引起的,你可以选择自动进行错误处理或者无视他。 通过配置可以实现,当 master 出现故障,可以在重新连接 master 之前,自动尝试连接 一台 slave 去自动处理故障,或者无视这个错误。因为 自动故障转移 并不是一个十分安全的方式,这里就不做过多讨论了,在 concepts section 中会有更多的说明。

示例 #1 手动故障转移,可选自动

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "simulate_slave_failure",
                "port": "0"
            },
            "slave_1": {
                "host": "127.0.0.1",
                "port": 3311
            }
        },
       "filters": { "roundrobin": [] }
    }
 }

示例 #2 手动故障转移

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

$sql = "SELECT 1 FROM DUAL";

/* error handling as it should be done regardless of the plugin */
if (!($res = $link->query($sql))) {
  /* plugin specific: check for connection error */
  switch ($link->errno) {
    case 2002:
    case 2003:
    case 2005:
      printf("Connection error - trying next slave!\n");
      /* load balancer will pick next slave */
      $res = $link->query($sql);
      break;
    default:
      /* no connection error, failover is unlikely to help */
      die(sprintf("SQL error: [%d] %s", $link->errno, $link->error));
      break;
  }
}
if ($res) {
  var_dump($res->fetch_assoc());
}
?>

分区和分片

数据库群组是由于各种各样的原因建立的,他可以提升处理能力、容忍错误,并且 提升大量服务器同时工作的的性能。群组有时会组合分区和共享功能,来将大量复杂的任务 分拆成更加简单的任务,更加可控的单元。

插件可以支持各种各样的 MySQL 群组,一些群组会内置一些分区和共享的方法,他们可以 被透明的使用。插件支持最常用的 MySQL 主从同步表过滤和共享 (应用级分区)。

MySQL 主从同步支持过滤方式的分区,他可以让你创建所有数据库同步,或者部分数据库同步。 这样就要求应用能够拥有同样的策略,你可以通过 node_groups 手动的支持这个策略,或者使用实验性质的表过滤器。

从 1.5.0 版本开始,可以通过节点组过滤和 SQL hints 完成手动的分区和共享。 节点组过滤器可以让你将 master 和 slave 命名成一个符号。 范例中, master_0slave_0 被放在一个命名为 Partition_A 的组中。他们能够完全的组成一个群组。 例如,你可以使用一个节点群组用于共享,并且使用使用群组名称作为一个地址共享, 就像 Shard_A_Range_0_100

示例 #1 Cluster node groups

{
  "myapp": {
       "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "simulate_slave_failure",
                "port": "0"
            },
            "slave_1": {
                "host": "127.0.0.1",
                "port": 3311
            }
        },
        "filters": {
            "node_groups": {
                "Partition_A" : {
                    "master": ["master_0"],
                    "slave": ["slave_0"]
                }
            },
           "roundrobin": []
        }
    }
}

示例 #2 通过 SQL hints 完成手动分区

<?php
function select($mysqli, $msg, $hint = '') {
  /* Note: weak test, two connections to two servers may have the same thread id */
  $sql = sprintf("SELECT CONNECTION_ID() AS _thread, '%s' AS _hint FROM DUAL", $msg);
  if ($hint) {
    $sql = $hint . $sql;
  }
  if (!($res = $mysqli->query($sql))) {
    printf("[%d] %s", $mysqli->errno, $mysqli->error);
    return false;
  }
  $row =  $res->fetch_assoc();
  printf("%d - %s - %s\n", $row['_thread'], $row['_hint'], $sql);
  return true;
}

$mysqli = new mysqli("myapp", "user", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* All slaves allowed */
select($mysqli, "slave_0");
select($mysqli, "slave_1");

/* only servers of node group "Partition_A" allowed */
select($mysqli, "slave_1", "/*Partition_A*/");
select($mysqli, "slave_1", "/*Partition_A*/");
?>
6804 - slave_0 - SELECT CONNECTION_ID() AS _thread, 'slave1' AS _hint FROM DUAL
2442 - slave_1 - SELECT CONNECTION_ID() AS _thread, 'slave2' AS _hint FROM DUAL
6804 - slave_0 - /*Partition_A*/SELECT CONNECTION_ID() AS _thread, 'slave1' AS _hint FROM DUAL
6804 - slave_0 - /*Partition_A*/SELECT CONNECTION_ID() AS _thread, 'slave1' AS _hint FROM DUAL

默认的,插件使用所有配置的 master 和 slave 进行查询操作。但是如果一个查询,使用 /*node_group*/ 的 SQL hint,那么插件将只使用在 node_group 列出的服务器进行查询操作。所以,SELECT 查询操作,只会在 /*Partition_A*/ 列出的 slave_0 中进行。

MySQL Fabric

Note: Version requirement and status

Work on supporting MySQL Fabric started in version 1.6. Please, consider the support to be of pre-alpha quality. The manual may not list all features or feature limitations. This is work in progress.

Sharding is the only use case supported by the plugin to date.

Note: MySQL Fabric concepts

Please, check the MySQL reference manual for more information about MySQL Fabric and how to set it up. The PHP manual assumes that you are familiar with the basic concepts and ideas of MySQL Fabric.

MySQL Fabric is a system for managing farms of MySQL servers to achive High Availability and optionally support sharding. Technically, it is a middleware to manage and monitor MySQL servers.

Clients query MySQL Fabric to obtain lists of MySQL servers, their state and their roles. For example, clients can can request a list of slaves for a MySQL Replication group and whether they are ready to handle SQL requests. Another example is a cluster of sharded MySQL servers where the client seeks to know which shard to query for a given table and shard key. If configured to use Fabric, the plugin uses XML RCP over HTTP to obtain the list at runtime from a MySQL Fabric host. The XML remote procedure call itself is done in the background and transparent from a developers point of view.

Instead of listing MySQL servers directly in the plugins configuration file it contains a list of one or more MySQL Fabric hosts

示例 #1 Plugin config: Fabric hosts instead of MySQL servers

{
    "myapp": {
        "fabric": {
            "hosts": [
                {
                    "host" : "127.0.0.1",
                    "port" : 8080
                }
            ]
        }
    }
}

Users utilize the new functions mysqlnd_ms_fabric_select_shard and mysqlnd_ms_fabric_select_global to switch to the set of servers responsible for a given shard key. Then, the plugin picks an appropriate server for running queries on. When doing so, the plugin takes care of additional load balancing rules set.

The below example assumes that MySQL Fabric has been setup to shard the table test.fabrictest using the id column of the table as a shard key.

示例 #2 Manual partitioning using SQL hints

<?php
$mysqli = new mysqli("myapp", "user", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* Create a global table - a table available on all shards */
mysqlnd_ms_fabric_select_global($mysqli, "test.fabrictest");
if (!$mysqli->query("CREATE TABLE test.fabrictest(id INT NOT NULL PRIMARY KEY)"))
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

/* Switch connection to appropriate shard and insert record */
mysqlnd_ms_fabric_select_shard($mysqli, "test.fabrictest", 10);
if (!($res = $mysqli->query("INSERT INTO fabrictest(id) VALUES (10)")))
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

/* Try to read newly inserted record */
mysqlnd_ms_fabric_select_shard($mysqli, "test.fabrictest", 10);
if (!($res = $mysqli->query("SELECT id FROM test WHERE id = 10")))
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
?>

The example creates the sharded table, inserts a record and reads the record thereafter. All SQL data definition language (DDL) operations on a sharded table must be applied to the so called global server group. Prior to creatingor altering a sharded table, mysqlnd_ms_fabric_select_global is called to switch the given connection to the corresponsing servers of the global group. Data manipulation (DML) SQL statements must be sent to the shards directly. The mysqlnd_ms_fabric_select_shard switches a connection to shards handling a certain shard key.

概念

目录

这里说明关于插件的一些相关概念,与使用数据库集群的 MySQL 主从同步对于开发 的一些影响。为了能够让插件更好的工作,需要阅读和理解这些概念。

Architecture

mysqlnd 作为一个 PHP 扩展完成主从同步和负载均衡。他使用 C 语言编写, 从底层嵌入 PHP。伴随 PHP 解释器的启动,他以模块的方式嵌入 PHP 引擎。 他使用 mysqlnd 名称注册在引擎中, 并且使用 mysqlnd 自己的 C 方法替换系统默认操作。

在 PHP 脚本运行期间,他检查所有通过 mysqlnd 发送给 MySQL 服务器的指令。 如果指令时只读的,那么将会发送给排至的 slave 服务器。通过判断语句 是否以 SELECT 开头,决定他是否是只读指令。或者通过 SQL hints /*ms=slave*/ 指定 slave 运行,或者通过 SQL hints /*ms=last_used*/ 指定通过上一条查询的连接运行。 其他情况下,指令会被发送到 MySQL 主从同步的 master 服务器执行。

为了更好的移植性,应用应该使用 MYSQLND_MS_MASTER_SWITCH, MYSQLND_MS_SLAVE_SWITCH, 和 MYSQLND_MS_LAST_USED_SWITCH mysqlnd_ms 预定义常量, 替代 SQL hints 的使用,例如:/*ms=slave*/

插件控制所有到 master 和 slave 的链接。对于应用来说,只需要控制一个连接。 然而这个应用控制的链接,其实是插件管理的连接池中的一个。插件代理了这些 到 master 的链接,并且管理很多的到达 slave 的链接。

数据库连接的状态,由事务、状态、事务设定、字符集设定、临时表等内容组成。 插件在事务执行的过程中和自动提交指令执行中,维护同样的链接状态。有效维护这些 状态并不容易,当运行 BEGIN TRANSACTION 指令后,插件将 控制权移交给用户。

连接池与切换

插件控制 PHP MySQL 链接,完成同步和负载均衡,他并不会改变现有的 PHP MySQL 扩展的方法使用 (mysqli, mysql, 和 PDO_MYSQL) 现有的应用并不需要 更新他们代码,或者使用新的 API,但是若操作行为改变,还是需要一些修改的。

插件结果下面这些扩展对于 MySQL 连接的控制, mysqli, mysql, 和 PDO_MYSQL。 并且为 mysqli, mysql, 和 PDO_MYSQL 提供一个本地的连接池 完成 MySQL 主从同步的 master 和 slave 通讯控制。插件会代理所有的 到达 master 和 slave 的查询请求。 在某一时刻一个连接到 master 的链接,会在稍后变更为 slave 连接,或者 依然保持 master 连接。在执行非事务处理中,控制和替换 PHP MySQL 的网络链接。

每个 MySQL 连接都有他的状态,在连接池中的每个连接可以有不同的状态。 当插件将一个写入连接变更为另外一个的时候,链接状态可能被改变。应用 需要关注这个问题。

下面列出连接状态的内容,他可能并不完整。

  • 事务状态
  • 临时表
  • 表锁
  • Session 系统变量和用户变量
  • 当前使用的数据库 USE 和其他束缚 SQL 指令的状态
  • 预执行语句
  • HANDLER 变量
  • 通过 GET_LOCK () 获得的锁

连接替换将在语句执行前进行,在下一个语句执行以前,插件不会变更连接。

Note: 同步的问题

请参考 MySQL 参考手册中关于 » replication features 的相关内容。一些限制跟这个 PHP 插件无感,但是与 MySQL 的主从同步相关。

广播消息

插件的设计哲学是只有完全控制的链接,插件会在连接池排列连接的状态,或者由于 一些安全因素也会这么做。只有很少的操作改变连接状态会失败,在这样的分类当中。

下面列出了哪些客户端的库,会改变连接状态,并且会将它广播到连接池中所有 打开的链接当中。

任何下面列出的内容被执行,插件会轮循所有打开的 master 和 slave 连接, 轮循会在操作了所有的服务器后停止。这个轮循不会影响服务器连接失败的状态。 库函数的触发器可能以备检测到失败,并且通过用户 API 函数广播。

Library call Notes Version
change_user() Called by the mysqli_change_user user API call. Also triggered upon reuse of a persistent mysqli connection. Since 1.0.0.
select_db Called by the following user API calls: mysql_select_db, mysql_list_tables, mysql_db_query, mysql_list_fields, mysqli_select_db. Note, that SQL USE is not monitored. Since 1.0.0.
set_charset() Called by the following user API calls: mysql_set_charset. mysqli_set_charset. Note, that SQL SET NAMES is not monitored. Since 1.0.0.
set_server_option() Called by the following user API calls: mysqli_multi_query, mysqli_real_query, mysqli_query, mysql_query. Since 1.0.0.
set_client_option() Called by the following user API calls: mysqli_options, mysqli_ssl_set, mysqli_connect, mysql_connect, mysql_pconnect. Since 1.0.0.
set_autocommit() Called by the following user API calls: mysqli_autocommit, PDO::setAttribute(PDO::ATTR_AUTOCOMMIT). Since 1.0.0. PHP >= 5.4.0.
ssl_set() Called by the following user API calls: mysqli_ssl_set. Since 1.1.0.

广播和被动连接

连接打开以后,插件无法代理或者记录其上所有的设定。如果采用 lazy connections. 这非常重要。被动连接方式,客户端在发起第一次指令的时候,连接才被建立。 插件默认的采用这种被动连接方式。

下面的这些库调用,将在被动连接建立以后执行。这有助于确信所有连接池中 连接的状态存在可比性。

Library call Notes Version
change_user() User, password and database recorded for future use. Since 1.1.0.
select_db Database recorded for future use. Since 1.1.0.
set_charset() Calls set_client_option(MYSQL_SET_CHARSET_NAME, charset) on lazy connection to ensure charset will be used upon opening the lazy connection. Since 1.1.0.
set_autocommit() Adds SET AUTOCOMMIT=0|1 to the list of init commands of a lazy connection using set_client_option(MYSQL_INIT_COMMAND, "SET AUTOCOMMIT=...%quot;). Since 1.1.0. PHP >= 5.4.0.

Caution

连接状态不仅仅会被 API 调用改变。所以,即使插件监控了所有的 API 调用, 应用也要在这方面关注变化。最后,对于连接状态的维护,是应用应该完成的事情。

字符集和字符串换码

当使用默认的被动连接时,若应用尝试在连接建立以前对 SQL 语句中的字符进行转码, 是不可能完成的。因为连接建立以前,并不知道连接需要的字符集是甚么。

在 1.4.0 以后版本中,通过配置中的 server_charset 设置可以解决这个问题。

需要注意已经转换为某种字符集,但是连接的结果采用了另外一种不同的字符集。 插件控制的链接和连接池中的每个连接可能采用了不同的默认字符集,所以建议配置 服务器采用统一的默认字符集设定。配置文件中的 server_charset 可以很好的处理这种情况,如果使用它,插件将对每一个新打开的链接设定默认的字符集。

事务控制

事务控制已经从根本上被改变了,一个 SQL 事务是运行在一个数据库服务器中的 一个或者一组 SQL 语句。

默认情况下,插件并不关心 SQL 事务处理,插件会在每个 SQL 执行时进行负载均衡, 这就可能在事务执行的中间更换了连接。这对事务执行来说是不可以的,所以默认 配置的插件并不是事务安全的。

MySQL 负载均衡需要从事务开始到终止时,处于连续的状态。这种连续控制,可以使用 监控 API 调用,或者使用 SQL hints。具体插件可以支持哪种方式,基于您使用的 PHP 版本。API 调用监控,需要 PHP 5.4.0 以上版本。就像其他的 MySQL 负载均衡控制 一样,本插件无法自动识别事务的起始和终止边界。采用 API 监控方式是对现有应用 改变最小的方式。

可以在 examples section 找到使用 SQL hints 和 API 监控的范例。在 API 监控作用下,插件会关注事务的执行。

从 PHP 5.4.0 版本开始,mysqlnd 库允许调用 set_autocommit() 他用于检测 autocommit 设定。

PHP MySQL 扩展调用查询语句 (例如 SET AUTOCOMMIT=0|1) 或者 set_autocommit() 来控制 autocommit 设置。 如果通过 set_autocommit() 来设置,那么插件能够识别事务。 插件无法知道通过查询语句设定的 autocommit 状态。 set_autocommit() 会被 mysqli_autocommitPDO::setAttribute(PDO::ATTR_AUTOCOMMIT) 调用。

插件的配置 trx_stickiness=master 可以用来让插件识别事务处理。在这种情况下,如果 autocommit 被禁用,那么插件将终止负载均衡, 所有的语句都将交给 master执行,直到 autocommit 被启用。

应用程序若不想针对事务执行设置 SQL hints,那么就需要使用 API 监控来完成对 事务处理的支持,那么请注意一定要使用上面列出的,可以识别 autocommit 状态变化 的 API 调用。

基于 API 的事务处理边界识别,是从 PHP 5.5.0 和 本插件 1.5.0 版本开始的,并且 不仅仅识别 <span class="function">mysqli_autocommit 也可以识别 <span class="function">mysqli_begin,<span class="function">mysqli_commit 和 <span class="function">mysqli_rollback。

错误处理

应用程序使用本插件,应该针对用户的 API 调用实现一些错误处理。并且由于插件 改变了连接控制,API 调用可能返回不可预期的错误。如果插件被用于连接控制中, 那么连接将不在代表一个独立的网络链接,他是一个连接池。那么一个错误编号和 错误消息将被设置在连接控制中,那么他可能被设置在任何一个实际的连接中。

如果使用默认的被动连接,那么连接再实际查询执行以前是不建立实际连接的。 这样一个执行语句的 API 调用会产生一个连接错误。下面的范例中,当尝试在 slave 中执行一个语句的时候将产生一个错误。连接错误的产生是因为在配置文件中 没有设定一个有效的 slave。

示例 #1 Provoking a connection error

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "invalid_host_name",
            }
        },
        "lazy_connections": 1
    }
}

明确的指定被动连接设定只是为了范例目的使用。

示例 #2 在查询执行时产生连接错误

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (mysqli_connect_errno())
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* 连接 1:在连接中绑定 SQL 用户定义变量,没有 SELECT 所以在 master 上运行 */
if (!$mysqli->query("SET @myrole='master'")) {
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}

/* 连接 2:运行 SELECT 在 slave,产生一个连接错误 */
if (!($res = $mysqli->query("SELECT @myrole AS _role"))) {
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
} else {
 $row = $res->fetch_assoc();
 $res->close();
 printf("@myrole = '%s'\n", $row['_role']);
}
$mysqli->close();
?>

以上例程的输出类似于:

PHP Warning:  mysqli::query(): php_network_getaddresses: getaddrinfo failed: Name or service not known in %s on line %d
PHP Warning:  mysqli::query(): [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known (trying to connect via tcp://invalid_host_name:3306) in %s on line %d
[2002] php_network_getaddresses: getaddrinfo failed: Name or service not known

应用程序希望通过有效的错误处理控制这种连接错误。

处于使用的目的,应用程序应该希望控制这些错误,典型的错误内容 2002 (CR_CONNECTION_ERROR) - Can't connect to local MySQL server through socket '%s' (%d), 2003 (CR_CONN_HOST_ERROR) - Can't connect to MySQL server on '%s' (%d)2005 (CR_UNKNOWN_HOST) - Unknown MySQL server host '%s' (%d)。 例如,应用程序可以判断这些错误编号,进而手动的执行某些错误处理。插件并不会自动的进行 这些错误处理,包括 master 错误处理,因为这些并不是透明的操作。

示例 #3 产生一个连接错误

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost"
            }
        },
        "slave": {
            "slave_0": {
                "host": "invalid_host_name"
            },
            "slave_1": {
                "host": "192.168.78.136"
            }
        },
        "lazy_connections": 1,
        "filters": {
            "roundrobin": [

            ]
        }
    }
}

明确的指定被动连接只为了进行范例使用,包括使用默认的负载均衡策略 random once

示例 #4 非常基础的错误处理

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (mysqli_connect_errno())
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* Connection 1, connection bound SQL user variable, no SELECT thus run on master */
if (!$mysqli->query("SET @myrole='master'")) {
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}

/* 连接 2:第一个 Slave 执行 */
$res = $mysqli->query("SELECT VERSION() AS _version");
/* 强硬的进行错误处理 */
if (2002 == $mysqli->errno || 2003 == $mysqli->errno || 2004 == $mysqli->errno) {
  /* 连接 3:第一个 slave 连接失败,尝试下一个 slave 连接 */
  $res = $mysqli->query("SELECT VERSION() AS _version");
}

if (!$res) {
  printf("ERROR, [%d] '%s'\n", $mysqli->errno, $mysqli->error);
} else {
 /* 从连接 3 中获取错误信息,他并没有错误 */
 printf("SUCCESS, [%d] '%s'\n", $mysqli->errno, $mysqli->error);
 $row = $res->fetch_assoc();
 $res->close();
 printf("version = %s\n", $row['_version']);
}
$mysqli->close();
?>

以上例程的输出类似于:

[1045] Access denied for user 'username'@'localhost' (using password: YES)
PHP Warning:  mysqli::query(): php_network_getaddresses: getaddrinfo failed: Name or service not known in %s on line %d
PHP Warning:  mysqli::query(): [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known (trying to connect via tcp://invalid_host_name:3306) in %s on line %d
SUCCESS, [0] ''
version = 5.6.2-m5-log

由于一些原因,连接控制并不可能很容易在所有网络连接中检查所有的错误。 例如,我们假设在连接池中有 3 个网络链接,一个连接是 master 连接,2个是 slave 链接。 应用程序通过 <span class="function">mysqli_select_db API 调用改变当前操作数据库, 插件监控到这个函数,并且尝试更改当前的所有连接来统一他们的链接状态。如果 master 已经成功的更改了数据库,两个 slave 连接更改失败,那么在使用第一个 slave 连接的时候, 其中会包含一个连接错误。对于第二个 slave 链接也是一样的,那么在第一个 slave 上的 错误信息将被丢失。

这种情况下,可以通过检查 E_WARNING 类型的错误,或者检查 mysqlnd_ms debug and trace log

短错误

一些分布式的数据库群组使用短错误。一个短错误只是一段时间内的一个临时错误。 在一定的顶一下,这种忽略短错误并且重新在同一个数据库服务器中进行尝试是 安全的,尝试处理对客户端不产生影响。客户端将不会被迫终止他们的工作,或者去处理 另外一个数据库服务器的错误。他们将进入一个尝试处理错误的循环,而不需要等待错误 信息消失。例如,当使用 MySQL Cluster时,可以看到这种短错误信息。他们并不会被 绑定在特定的群组解决方案中。

插件可以提供在短错误中的自动尝试处理循环。这将提高分布处理的透明度,并且对于 应用程序从一个单独服务器运行一直到数据库服务群组执行变得更加简单。

自动的尝试循环,将不断的尝试,直到用户配置文件指定的次数,并且根据配置指定的 间隔时间进行短暂的等待。如果错误在循环过程中消失,应用程序将不会再看到这个 错误信息。如果错误没有消失,错误将被提交给应用程序进行处理。

下面的范例中,duplicate key 的错误内容在提交给应用程序以前,会被尝试处理 2 次, 两次尝试之间间隔 100 ms。

示例 #1 Provoking a transient error

mysqlnd_ms.enable=1
mysqlnd_ms.collect_statistics=1
{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.78.136",
                "port": "3306"
            }
       },
       "transient_error": {
          "mysql_error_codes": [
            1062
          ],
          "max_retries": 2,
          "usleep_retry": 100
       }
    }
}

示例 #2 短错误尝试循环

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (mysqli_connect_errno())
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

if (!$mysqli->query("DROP TABLE IF EXISTS test") ||
    !$mysqli->query("CREATE TABLE test(id INT PRIMARY KEY)") ||
    !$mysqli->query("INSERT INTO test(id) VALUES (1))")) {
  printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}

/* Retry loop is completely transparent. Checking statistics is
 the only way to know about implicit retries */
$stats = mysqlnd_ms_get_stats();
printf("Transient error retries before error: %d\n", $stats['transient_error_retries']);

/* Provoking duplicate key error to see statistics change */
if (!$mysqli->query("INSERT INTO test(id) VALUES (1))")) {
  printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}

$stats = mysqlnd_ms_get_stats();
printf("Transient error retries after error: %d\n", $stats['transient_error_retries']);

$mysqli->close();
?>

以上例程的输出类似于:

Transient error retries before error: 0
[1062] Duplicate entry '1' for key 'PRIMARY'
Transient error retries before error: 2

Because the execution of the retry loop is transparent from a users point of view, the example checks the statistics provided by the plugin to learn about it.

As the example shows, the plugin can be instructed to consider any error transient regardless of the database servers error semantics. The only error that a stock MySQL server considers temporary has the error code 1297. When configuring other error codes but 1297 make sure your configuration reflects the semantics of your clusters error codes.

The following mysqlnd C API calls are monitored by the plugin to check for transient errors: query(), change_user(), select_db(), set_charset(), set_server_option() prepare(), execute(), set_autocommit(), tx_begin(), tx_commit(), tx_rollback(), tx_commit_or_rollback(). The corresponding user API calls have similar names.

The maximum time the plugin may sleep during the retry loop depends on the function in question. The a retry loop for query(), prepare() or execute() will sleep for up to max_retries * usleep_retry milliseconds.

However, functions that control connection state are dispatched to all all connections. The retry loop settings are applied to every connection on which the command is to be run. Thus, such a function may interrupt program execution for longer than a function that is run on one server only. For example, set_autocommit() is dispatched to connections and may sleep up to (max_retries * usleep_retry) * number_of_open_connections) milliseconds. Please, keep this in mind when setting long sleep times and large retry numbers. Using the default settings of max_retries=1, usleep_retry=100 and lazy_connections=1 it is unlikely that you will ever see a delay of more than 1 second.

错误处理

默认情况下,错误处理应该由用户来处理,应用程序应该检查数据库函数的返回值并且 处理其中可能产生的错误内容。例如,如果插件为一个只读查询选择了一个已经不可用 的 slave,那么将会在执行以后产生一个错误。

默认:手动处理错误

It is up to the application to handle the error and, if required, re-issue the query to trigger the selection of another slave server for statement execution. The plugin will make no attempts to failover automatically, because the plugin cannot ensure that an automatic failover will not change the state of the connection. For example, the application may have issued a query which depends on SQL user variables which are bound to a specific connection. Such a query might return incorrect results if the plugin would switch the connection implicitly as part of automatic failover. To ensure correct results, the application must take care of the failover, and rebuild the required connection state. Therefore, by default, no automatic failover is performed by the plugin.

A user that does not change the connection state after opening a connection may activate automatic failover. Please note, that automatic failover logic is limited to connection attempts. Automatic failover is not used for already established connections. There is no way to instruct the plugin to attempt failover on a connection that has been connected to MySQL already in the past.

Automatic failover

The failover policy is configured in the plugins configuration file, by using the failover configuration directive.

Automatic and silent failover can be enabled through the failover configuration directive. Automatic failover can either be configured to try exactly one master after a slave failure or, alternatively, loop over slaves and masters before returning an error to the user. The number of connection attempts can be limited and failed hosts can be excluded from future load balancing attempts. Limiting the number of retries and remembering failed hosts are considered experimental features, albeit being reasonable stable. Syntax and semantics may change in future versions.

Please note, since version 1.5.0 automatic failover is disabled for the duration of a transaction if transaction stickiness is enabled and transaction boundaries have been detected. The plugin will not switch connections for the duration of a transaction. It will also not perform automatic and silent failover. Instead an error will be thrown. It is then left to the user to handle the failure of the transaction. Please check, the trx_stickiness documentation how to do this.

A basic manual failover example is provided within the error handling section.

Standby servers

Using weighted load balancing, introduced in PECL/mysqlnd 1.4.0, it is possible to configure standby servers that are sparsely used during normal operations. A standby server that is primarily used as a worst-case standby failover target can be assigned a very low weight/priority in relation to all other servers. As long as all servers are up and running the majority of the workload is assigned to the servers which have hight weight values. Few requests will be directed to the standby system which has a very low weight value.

Upon failure of the servers with a high priority, you can still failover to the standby, which has been given a low load balancing priority by assigning a low weight to it. Failover can be some manually or automatically. If done automatically, you may want to combine it with the remember_failed option.

At this point, it is not possible to instruct the load balancer to direct no requests at all to a standby. This may not be much of a limitation given that the highest weight you can assign to a server is 65535. Given two slaves, of which one shall act as a standby and has been assigned a weight of 1, the standby will have to handle far less than one percent of the overall workload.

Failover and primary copy

Please note, if using a primary copy cluster, such as MySQL Replication, it is difficult to do connection failover in case of a master failure. At any time there is only one master in the cluster for a given dataset. The master is a single point of failure. If the master fails, clients have no target to fail over write requests. In case of a master outage the database administrator must take care of the situation and update the client configurations, if need be.

负载均衡

有 4 中复杂均衡策略,可以用于支持 MySQL slave 的配置。

random
当执行语句的时候随机选择一个服务器。

random once (默认值)
当第一个查询执行的时候,随机选择一个服务器,在本页面随后的查询中, 使用相同的一个服务器连接。

这是默认值,并且这种方式对于连接状态信息可能产生的变数影响最小。

round robin
轮循配置中的所有服务器。

user-defined via callback
可以用于制定任何一种其他的策略。

可以使用 random, roundrobin, 和 user filters 在插件的配置中,指定使用的 负载均衡策略。

服务器可以被设定权重。若果一个服务器的权重被设定为 2,那么在大量的操作后,可以看到 他使用的次数将是那些权重为 1 的服务器使用的 2 倍。这种优先级信息可以被非常方便的 在 heterogenous 环境中设定。例如,希望在一个更好的设备上执行更多查询, 或者希望在就近的设备中进行更多的查询,等等这些各种各样的不同原因使用。

Read-write splitting

The plugin executes read-only statements on the configured MySQL slaves, and all other queries on the MySQL master. Statements are considered read-only if they either start with SELECT, the SQL hint /*ms=slave*/, or if a slave had been chosen for running the previous query and the query starts with the SQL hint /*ms=last_used*/. In all other cases, the query will be sent to the MySQL replication master server. It is recommended to use the constants MYSQLND_MS_SLAVE_SWITCH, MYSQLND_MS_MASTER_SWITCH and MYSQLND_MS_LAST_USED_SWITCH instead of /*ms=slave*/. See also the list of mysqlnd_ms constants.

SQL hints are a special kind of standard compliant SQL comments. The plugin does check every statement for certain SQL hints. The SQL hints are described within the mysqlnd_ms constants documentation, constants that are exported by the extension. Other systems involved with the statement processing, such as the MySQL server, SQL firewalls, and SQL proxies, are unaffected by the SQL hints, because those systems are designed to ignore SQL comments.

The built-in read-write splitter can be replaced by a user-defined filter, see also the user filter documentation.

A user-defined read-write splitter can request the built-in logic to send a statement to a specific location, by invoking <span class="function">mysqlnd_ms_is_select.

Note:

The built-in read-write splitter is not aware of multi-statements. Multi-statements are seen as one statement. The splitter will check the beginning of the statement to decide where to run the statement. If, for example, a multi-statement begins with SELECT 1 FROM DUAL; INSERT INTO test(id) VALUES (1); ... the plugin will run it on a slave although the statement is not read-only.

Filter

Note: Version requirement

Filters exist as of mysqlnd_ms version 1.1.0-beta.

filters. PHP applications that implement a MySQL replication cluster must first identify a group of servers in the cluster which could execute a statement before the statement is executed by one of the candidates. In other words: a defined list of servers must be filtered until only one server is available.

The process of filtering may include using one or more filters, and filters can be chained. And they are executed in the order they are defined in the plugins configuration file.

Note: Explanation: comparing filter chaining to pipes

The concept of chained filters can be compared to using pipes to connect command line utilities on an operating system command shell. For example, an input stream is passed to a processor, filtered, and then transferred to be output. Then, the output is passed as input to the next command, which is connected to the previous using the pipe operator.

Available filters:

The random filter implements the 'random' and 'random once' load balancing policies. The 'round robin' load balancing can be configured through the roundrobin filter. Setting a 'user defined callback' for server selection is possible with the user filter. The quality_of_service filter finds cluster nodes capable of delivering a certain service, for example, read-your-writes or, not lagging more seconds behind the master than allowed.

Filters can accept parameters to change their behaviour. The random filter accepts an optional sticky parameter. If set to true, the filter changes load balancing from random to random once. Random picks a random server every time a statement is to be executed. Random once picks a random server when the first statement is to be executed and uses the same server for the rest of the PHP request.

One of the biggest strength of the filter concept is the possibility to chain filters. This strength does not become immediately visible because tje random, roundrobin and user filters are supposed to output no more than one server. If a filter reduces the list of candidates for running a statement to only one server, it makes little sense to use that one server as input for another filter for further reduction of the list of candidates.

An example filter sequence that will fail:

  • Statement to be executed: SELECT 1 FROM DUAL. Passed to all filters.
  • All configured nodes are passed as input to the first filter. Master nodes: master_0. Slave nodes:slave_0, slave_1
  • Filter: random, argument sticky=1. Picks a random slave once to be used for the rest of the PHP request. Output: slave_0.
  • Output of slave_0 and the statement to be executed is passed as input to the next filter. Here: roundrobin, server list passed to filter is: slave_0.
  • Filter: roundrobin. Server list consists of one server only, round robin will always return the same server.

If trying to use such a filter sequence, the plugin may emit a warning like (mysqlnd_ms) Error while creating filter '%s' . Non-multi filter '%s' already created. Stopping in %s on line %d. Furthermore, an appropriate error on the connection handle may be set.

A second type of filter exists: multi filter. A multi filter emits zero, one or multiple servers after processing. The quality_of_service filter is an example. If the service quality requested sets an upper limit for the slave lag and more than one slave is lagging behind less than the allowed number of seconds, the filter returns more than one cluster node. A multi filter must be followed by other to further reduce the list of candidates for statement execution until a candidate is found.

A filter sequence with the quality_of_service multi filter followed by a load balancing filter.

  • Statement to be executed: SELECT sum(price) FROM orders WHERE order_id = 1. Passed to all filters.
  • All configured nodes are passed as input to the first filter. Master nodes: master_0. Slave nodes: slave_0, slave_1, slave_2, slave_3
  • Filter: quality_of_service, rule set: session_consistency (read-your-writes) Output: master_0
  • Output of master_0 and the statement to be executed is passed as input to the next filter, which is roundrobin.
  • Filter: roundrobin. Server list consists of one server. Round robin selects master_0.

A filter sequence must not end with a multi filter. If trying to use a filter sequence which ends with a multi filter the plugin may emit a warning like (mysqlnd_ms) Error in configuration. Last filter is multi filter. Needs to be non-multi one. Stopping in %s on line %d. Furthermore, an appropriate error on the connection handle may be set.

Note: Speculation towards the future: MySQL replication filtering

In future versions, there may be additional multi filters. For example, there may be a table filter to support MySQL replication filtering. This would allow you to define rules for which database or table is to be replicated to which node of a replication cluster. Assume your replication cluster consists of four slaves (slave_0, slave_1, slave_2, slave_3) two of which replicate a database named sales (slave_0, slave_1). If the application queries the database slaves, the hypothetical table filter reduces the list of possible servers to slave_0 and slave_1. Because the output and list of candidates consists of more than one server, it is necessary and possible to add additional filters to the candidate list, for example, using a load balancing filter to identify a server for statement execution.

Service level and consistency

Note: Version requirement

Service levels have been introduced in mysqlnd_ms version 1.2.0-alpha. mysqlnd_ms_set_qos requires PHP 5.4.0 or newer.

The plugin can be used with different kinds of MySQL database clusters. Different clusters can deliver different levels of service to applications. The service levels can be grouped by the data consistency levels that can be achieved. The plugin knows about:

  • eventual consistency
  • session consistency
  • strong consistency

Depending how a cluster is used it may be possible to achieve higher service levels than the default one. For example, a read from an asynchronous MySQL replication slave is eventual consistent. Thus, one may say the default consistency level of a MySQL replication cluster is eventual consistency. However, if the master only is used by a client for reading and writing during a session, session consistency (read your writes) is given. PECL mysqlnd 1.2.0 abstracts the details of choosing an appropriate node for any of the above service levels from the user.

Service levels can be set through the qualify-of-service filter in the plugins configuration file and at runtime using the function <span class="function">mysqlnd_ms_set_qos.

The plugin defines the different service levels as follows.

Eventual consistency is the default service provided by an asynchronous cluster, such as classical MySQL replication. A read operation executed on an arbitrary node may or may not return stale data. The applications view of the data is eventual consistent.

Session consistency is given if a client can always read its own writes. An asynchronous MySQL replication cluster can deliver session consistency if clients always use the master after the first write or never query a slave which has not yet replicated the clients write operation.

The plugins understanding of strong consistency is that all clients always see the committed writes of all other clients. This is the default when using MySQL Cluster or any other cluster offering synchronous data distribution.

Service level parameters

Eventual consistency and session consistency service level accept parameters.

Eventual consistency is the service provided by classical MySQL replication. By default, all nodes qualify for read requests. An optional age parameter can be given to filter out nodes which lag more than a certain number of seconds behind the master. The plugin is using SHOW SLAVE STATUS to measure the lag. Please, see the MySQL reference manual to learn about accuracy and reliability of the SHOW SLAVE STATUS command.

Session consistency (read your writes) accepts an optional GTID parameter to consider reading not only from the master but also from slaves which already have replicated a certain write described by its transaction identifier. This way, when using asynchronous MySQL replication, read requests may be load balanced over slaves while still ensuring session consistency.

The latter requires the use of client-side global transaction id injection.

Advantages of the new approach

The new approach supersedes the use of SQL hints and the configuration option master_on_write in some respects. If an application running on top of an asynchronous MySQL replication cluster cannot accept stale data for certain reads, it is easier to tell the plugin to choose appropriate nodes than prefixing all read statements in question with the SQL hint to enforce the use of the master. Furthermore, the plugin may be able to use selected slaves for reading.

The master_on_write configuration option makes the plugin use the master after the first write (session consistency, read your writes). In some cases, session consistency may not be needed for the rest of the session but only for some, few read operations. Thus, master_on_write may result in more read load on the master than necessary. In those cases it is better to request a higher than default service level only for those reads that actually need it. Once the reads are done, the application can return to default service level. Switching between service levels is only possible using <span class="function">mysqlnd_ms_set_qos.

Performance considerations

A MySQL replication cluster cannot tell clients which slaves are capable of delivering which level of service. Thus, in some cases, clients need to query the slaves to check their status. PECL mysqlnd_ms transparently runs the necessary SQL in the background. However, this is an expensive and slow operation. SQL statements are run if eventual consistency is combined with an age (slave lag) limit and if session consistency is combined with a global transaction ID.

If eventual consistency is combined with an maximum age (slave lag), the plugin selects candidates for statement execution and load balancing for each statement as follows. If the statement is a write all masters are considered as candidates. Slaves are not checked and not considered as candidates. If the statement is a read, the plugin transparently executes SHOW SLAVE STATUS on every slaves connection. It will loop over all connections, send the statement and then start checking for results. Usually, this is slightly faster than a loop over all connections in which for every connection a query is send and the plugin waits for its results. A slave is considered a candidate if SHOW SLAVE STATUS reports Slave_IO_Running=Yes, Slave_SQL_Running=Yes and Seconds_Behind_Master is less or equal than the allowed maximum age. In case of an SQL error, the plugin emits a warning but does not set an error on the connection. The error is not set to make it possible to use the plugin as a drop-in.

If session consistency is combined with a global transaction ID, the plugin executes the SQL statement set with the fetch_last_gtid entry of the global_transaction_id_injection section from the plugins configuration file. Further details are identical to those described above.

In version 1.2.0 no additional optimizations are done for executing background queries. Future versions may contain optimizations, depending on user demand.

If no parameters and options are set, no SQL is needed. In that case, the plugin consider all nodes of the type shown below.

  • eventual consistency, no further options set: all masters, all slaves
  • session consistency, no further options set: all masters
  • strong consistency (no options allowed): all masters

Throttling

The quality of service filter can be combined with Global transaction IDs to throttle clients. Throttling does reduce the write load on the master by slowing down clients. If session consistency is requested and global transactions idenentifier are used to check the status of a slave, the check can be done in two ways. By default a slave is checked and skipped immediately if it does not match the criteria for session consistency. Alternatively, the plugin can wait for a slave to catch up to the master until session consistency is possible. To enable the throttling, you have to set wait_for_gtid_timeout configuration option.

Global transaction IDs

Note: Version requirement

Client side global transaction ID injection exists as of mysqlnd_ms version 1.2.0-alpha. Transaction boundaries are detected by monitoring API calls. This is possible as of PHP 5.4.0. Please, see also Transaction handling.

As of MySQL 5.6.5-m8 the MySQL server features built-in global transaction identifiers. The MySQL built-in global transaction ID feature is supported by PECL/mysqlnd_ms 1.3.0-alpha or later. Neither are client-side transaction boundary monitoring nor any setup activities required if using the server feature.

Idea and client-side emulation

PECL/mysqlnd_ms can do client-side transparent global transaction ID injection. In its most basic form, a global transaction identifier is a counter which is incremented for every transaction executed on the master. The counter is held in a table on the master. Slaves replicate the counter table.

In case of a master failure a database administrator can easily identify the most recent slave for promiting it as a new master. The most recent slave has the highest transaction identifier.

Application developers can ask the plugin for the global transaction identifier (GTID) for their last successful write operation. The plugin will return an identifier that refers to an transaction no older than that of the clients last write operation. Then, the GTID can be passed as a parameter to the quality of service (QoS) filter as an option for session consistency. Session consistency ensures read your writes. The filter ensures that all reads are either directed to a master or a slave which has replicated the write referenced by the GTID.

When injection is done

The plugin transparently maintains the GTID table on the master. In autocommit mode the plugin injects an UPDATE statement before executing the users statement for every master use. In manual transaction mode, the injection is done before the application calls commit() to close a transaction. The configuration option report_error of the GTID section in the plugins configuration file is used to control whether a failed injection shall abort the current operation or be ignored silently (default).

Please note, the PHP version requirements for transaction boundary monitoring and their limits.

Limitations

Client-side global transaction ID injection has shortcomings. The potential issues are not specific to PECL/mysqlnd_ms but are rather of general nature.

  • Global transaction ID tables must be deployed on all masters and replicas.
  • The GTID can have holes. Only PHP clients using the plugin will maintain the table. Other clients will not.
  • Client-side transaction boundary detection is based on API calls only.
  • Client-side transaction boundary detection does not take implicit commit into account. Some MySQL SQL statements cause an implicit commit and cannot be rolled back.

Using server-side global transaction identifier

Starting with PECL/mysqlnd_ms 1.3.0-alpha the MySQL 5.6.5-m8 or newer built-in global transaction identifier feature is supported. Use of the server feature lifts all of the above listed limitations. Please, see the MySQL Reference Manual for limitations and preconditions for using server built-in global transaction identifiers.

Whether to use the client-side emulation or the server built-in functionality is a question not directly related to the plugin, thus it is not discussed in depth. There are no plans to remove the client-side emulation and you can continue to use it, if the server-side solution is no option. This may be the case in heterogenous environments with old MySQL server or, if any of the server-side solution limitations is not acceptable.

From an applications perspective there is hardly a difference in using one or the other approach. The following properties differ.

  • Client-side emulation, as shown in the manual, is using an easy to compare sequence number for global transactions. Multi-master is not handled to keep the manual examples easy. Server-side built-in feature is using a combination of a server identifier and a sequence number as a global transaction identifier. Comparison cannot use numeric algebra. Instead a SQL function must be used. Please, see the MySQL Reference Manual for details.
  • Plugin global transaction ID statistics are only available with client-side emulation because they monitor the emulation.

Note: Global transaction identifiers in distributed systems

Global transaction identifiers can serve multiple purposes in the context of distributed systems, such as a database cluster. Global transaction identifiers can be used for, for example, system wide identification of transactions, global ordering of transactions, heartbeat mechanism and for checking the replication status of replicas. PECL/mysqlnd_ms, a clientside driver based software, does focus on using GTIDs for tasks that can be handled at the client, such as checking the replication status of replicas for asynchronous replication setups.

Cache integration

Note: 版本需求

功能需要 PECL/mysqlnd_ms 1.3.0-beta 以上版本,和 PECL/mysqlnd_qc 1.1.0-alpha 以上版本。PECL/mysqlnd_ms 必须编译的时候支持这个功能,需要 PHP 5.4.0 以上版本。

Note: Setup: extension load order

PECL/mysqlnd_ms 必须在 PECL/mysqlnd_qc 前面装载。

Note: 功能稳定性

继承的缓存提供 beta 品质。

Note: 适用的 MySQL 集群

这个功能主要为 MySQL 主从同步提供支持,目前不支持其他的 MySQL 集群方式。如果用它 替代客户端查询缓存,用户必须手动控制 PECL/mysqlnd_qc。

Support for MySQL replication clusters (asynchronous primary copy) is the main focus of PECL/mysqlnd_ms. The slaves of a MySQL replication cluster may or may not reflect the latest updates from the master. Slaves are asynchronous and can lag behind the master. A read from a slave is eventual consistent from a cluster-wide perspective.

The same level of consistency is offered by a local cache using time-to-live (TTL) invalidation strategy. Current data or stale data may be served. Eventually, data searched for in the cache is not available and the source of the cache needs to be accessed.

Given that both a MySQL Replication slave (asynchronous secondary) and a local TTL-driven cache deliver the same level of service it is possible to transparently replace a remote database access with a local cache access to gain better possibility.

As of PECL/mysqlnd_ms 1.3.0-beta the plugin is capable of transparently controlling PECL/mysqlnd_ms 1.1.0-alpha or newer to cache a read-only query if explicitly allowed by setting an appropriate quality of service through mysqlnd_ms_set_qos. Please, see the quickstart for a code example. Both plugins must be installed, PECL/mysqlnd_ms must be compiled to support the cache feature and PHP 5.4.0 or newer has to be used.

Applications have full control of cache usage and can request fresh data at any time, if need be. Thec ache usage can be enabled and disabled time during the execution of a script. The cache will be used if <span class="function">mysqlnd_ms_set_qos sets the quality of service to eventual consistency and enables cache usage. Cache usage is disabled by requesting higher consistency levels, for example, session consistency (read your writes). Once the quality of service has been relaxed to eventual consistency the cache can be used again.

If caching is enabled for a read-only statement, PECL/mysqlnd_ms may inject SQL hints to control caching by PECL/mysqlnd_qc. It may modify the SQL statement it got from the application. Subsequent SQL processors are supposed to ignore the SQL hints. A SQL hint is a SQL comment. Comments must not be ignored, for example, by the database server.

The TTL of a cache entry is computed on a per statement basis. Applications set an maximum age for the data they want to retrieve using mysqlnd_ms_set_qos. The age sets an approximate upper limit of how many seconds the data returned may lag behind the master.

The following logic is used to compute the actual TTL if caching is enabled. The logic takes the estimated slave lag into account for choosing a TTL. If, for example, there are two slaves lagging 5 and 10 seconds behind and the maximum age allowed is 60 seconds, the TTL is set to 50 seconds. Please note, the age setting is no more than an estimated guess.

  • Check whether the statement is read-only. If not, don't cache.
  • If caching is enabled, check the slave lag of all configured slaves. Establish slave connections if none exist so far and lazy connections are used.
  • Send SHOW SLAVE STATUS to all slaves. Do not wait for the first slave to reply before sending to the second slave. Clients often wait long for replies, thus we send out all requests in a burst before fetching in a second stage.
  • Loop over all slaves. For every slave wait for its reply. Do not start checking another slave before the currently waited for slave has replied. Check for Slave_IO_Running=Yes and Slave_SQL_Running=Yes. If both conditions hold true, fetch the value of Seconds_Behind_Master. In case of any errors or if conditions fail, set an error on the slave connection. Skip any such slave connection for the rest of connection filtering.
  • Search for the maximum value of Seconds_Behind_Master from all slaves that passed the previous conditions. Subtract the value from the maximum age provided by the user with mysqlnd_ms_set_qos. Use the result as a TTL.
  • The filtering may sort out all slaves. If so, the maximum age is used as TTL, because the maximum lag found equals zero. It is perfectly valid to sort out all slaves. In the following it is up to subsequent filter to decide what to do. The built-in load balancing filter will pick the master.
  • Inject the appropriate SQL hints to enable caching by PECL/mysqlnd_qc.
  • Proceed with the connection filtering, e.g. apply load balancing rules to pick a slave.
  • PECL/mysqlnd_qc is loaded after PECL/mysqlnd_ms by PHP. Thus, it will see all query modifications of PECL/mysqlnd_ms and cache the query if instructed to do so.

The algorithm may seem expensive. SHOW SLAVE STATUS is a very fast operation. Given a sufficient number of requests and cache hits per second the cost of checking the slaves lag can easily outweight the costs of the cache decision.

Suggestions on a better algorithm are always welcome.

Supported clusters

Any application using any kind of MySQL cluster is faced with the same tasks:

  • Identify nodes capable of executing a given statement with the required service level
  • Load balance requests within the list of candidates
  • Automatic fail over within candidates, if needed

The plugin is optimized for fulfilling these tasks in the context of a classical asynchronous MySQL replication cluster consisting of a single master and many slaves (primary copy). When using classical, asynchronous MySQL replication all of the above listed tasks need to be mastered at the client side.

Other types of MySQL cluster may have lower requirements on the application side. For example, if all nodes in the cluster can answer read and write requests, no read-write splitting needs to be done (multi-master, update-all). If all nodes in the cluster are synchronous, they automatically provide the highest possible quality of service which makes choosing a node easier. In this case, the plugin may serve the application after some reconfiguration to disable certain features, such as built-in read-write splitting.

Note: Documentation focus

The documentation focusses describing the use of the plugin with classical asynchronous MySQL replication clusters (primary copy). Support for this kind of cluster has been the original development goal. Use of other clusters is briefly described below. Please note, that this is still work in progress.

Primary copy (MySQL Replication)

This is the primary use case of the plugin. Follow the hints given in the descriptions of each feature.

  • Configure one master and one or more slaves. Server configuration details are given in the setup section.
  • Use random load balancing policy together with the sticky flag.
  • If you do not plan to use the service level API calls, add the master on write flag.
  • Please, make yourself aware of the properties of automatic failover before adding a failover directive.
  • Consider the use of trx_stickiness to execute transactions on the primary only. Please, read carefully how it works before you rely on it.

示例 #1 Enabling the plugin (php.ini)

mysqlnd_ms.enable=1
mysqlnd_ms.config_file=/path/to/mysqlnd_ms_plugin.ini

示例 #2 Basic plugin configuration (mysqlnd_ms_plugin.ini) for MySQL Replication

{
  "myapp": {
    "master": {
      "master_1": {
        "host": "localhost",
        "socket": "\/tmp\/mysql57.sock"
      }
    },
    "slave": {
      "slave_0": {
        "host": "127.0.0.1",
        "port": 3308
      },
      "slave_1": {
        "host": "192.168.2.28",
        "port": 3306
      }
    },
    "filters": {
      "random": {
        "sticky": "1"
      }
    }
  }
}

Primary copy with multi primaries (MMM - MySQL Multi Master)

MySQL Replication allows you to create cluster topologies with multiple masters (primaries). Write-write conflicts are not handled by the replication system. This is no update anywhere setup. Thus, data must be partitioned manually and clients must redirected in accordance to the partitioning rules. The recommended setup is equal to the sharding setup below.

Manual sharding, possibly combined with primary copy and multiple primaries

Use SQL hints and the node group filter for clusters that use data partitioning but leave query redirection to the client. The example configuration shows a multi master setup with two shards.

示例 #3 Multiple primaries - multi master (php.ini)

mysqlnd_ms.enable=1
mysqlnd_ms.config_file=/path/to/mysqlnd_ms_plugin.ini
mysqlnd_ms.multi_master=1

示例 #4 Primary copy with multiple primaries and paritioning

{
  "myapp": {
    "master": {
      "master_1": {
        "host": "localhost",
        "socket": "\/tmp\/mysql57.sock"
      }
      "master_2": {
        "host": "192.168.2.27",
        "socket": "3306"
      }
    },
    "slave": {
      "slave_1": {
        "host": "127.0.0.1",
        "port": 3308
      },
      "slave_2": {
        "host": "192.168.2.28",
        "port": 3306
      }
    },
    "filters": {
      "node_groups": {
        "Partition_A" : {
          "master": ["master_1"],
          "slave": ["slave_1"]
        },
        "Partition_B" : {
          "master": ["master_2"],
          "slave": ["slave_2"]
        }
      },
      "roundrobin": []
    }
  }
}

The plugin can also be used with a loose collection of unrelated shards. For such a cluster, configure masters only and disable read write splitting. The nodes of such a cluster are called masters in the plugin configuration as they accept both reads and writes for their partition.

Using synchronous update everywhere clusters such as MySQL Cluster

MySQL Cluster is a synchronous cluster solution. All cluster nodes accept read and write requests. In the context of the plugin, all nodes shall be considered as masters.

Use the load balancing and fail over features only.

  • Disable the plugins built-in read-write splitting.
  • Configure masters only.
  • Consider random once load balancing strategy, which is the plugins default. If random once is used, only masters are configured and no SQL hints are used to force using a certain node, no connection switches will happen for the duration of a web request. Thus, no special handling is required for transactions. The plugin will pick one master at the beginning of the PHP script and use it until the script terminates.
  • Do not set the quality of service. All nodes have all the data. This automatically gives you the highest possible service quality (strong consistency).
  • Do not enable client-side global transaction injection. It is neither required to help with server-side fail over nor to assist the quality of service filter choosing an appropriate node.

Disabling built-in read-write splitting.

Configure masters only.

  • Set mysqlnd_ms.multi_master=1.
  • Do not configure any slaves.
  • Set failover=loop_before_master in the plugins configuration file to avoid warnings about the empty slave list and to make the failover logic loop over all configured masters before emitting an error. Please, note the warnings about automatic failover given in the previous sections.

示例 #5 Multiple primaries - multi master (php.ini)

mysqlnd_ms.enable=1
mysqlnd_ms.config_file=/path/to/mysqlnd_ms_plugin.ini
mysqlnd_ms.multi_master=1
mysqlnd_ms.disable_rw_split=1

示例 #6 Synchronous update anywhere cluster

"myapp": {
    "master": {
      "master_1": {
        "host": "localhost",
        "socket": "\/tmp\/mysql57.sock"
      },
      "master_2": {
        "host": "192.168.2.28",
        "port": 3306
      }
    },
    "slave": {
    },
    "filters": {
      "roundrobin": {
      }
    },
    "failover": {
      "strategy": "loop_before_master",
      "remember_failed": true
    }
  }
}

If running an update everywhere cluster that has no built-in partitioning to avoid hot spots and high collision rates, consider using the node groups filter to keep updates on a frequently accessed table on one of the nodes. This may help to reduce collision rates and thus improve performance.

XA/Distributed transactions

Note: Version requirement

XA related functions have been introduced in PECL/mysqlnd_ms version 1.6.0-alpha.

Note: Early adaptors wanted

The feature is currently under development. There may be issues and/or feature limitations. Do not use in production environments, although early lab tests indicate reasonable quality.

Please, contact the development team if you are interested in this feature. We are looking for real life feedback to complement the feature.

Below is a list of some feature restrictions.

  • The feature is not yet compatible with the MySQL Fabric support . This limitation is soon to be lifted.

    XA transaction identifier are currently restricted to numbers. This limitation will be lifted upon request, it is a simplification used during the initial implementation.

Note: MySQL server restrictions

The XA support by the MySQL server has some restrictions. Most noteably, the servers binary log may lack changes made by XA transactions in case of certain errors. Please, see the MySQL manual for details.

XA/Distributed transactions can spawn multiple MySQL servers. Thus, they may seem like a perfect tool for sharded MySQL clusters, for example, clusters managed with MySQL Fabric. PECL/mysqlnd_ms hides most of the SQL commands to control XA transactions and performs automatic administrative tasks in cases of errors, to provide the user with a comprehensive API. Users should setup the plugin carefully and be well aware of server restrictions prior to using the feature.

示例 #1 General pattern for XA transactions

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");

/* BEGIN */
mysqlnd_ms_xa_begin($mysqli, 1 /* xa id */);

/* run queries on various servers */
$mysqli->query("UPDATE some_table SET col_a = 1");
...

/* COMMIT */
mysqlnd_ms_xa_commit($link, 1);
?>

XA transactions use the two-phase commit protocol. The two-phase commit protocol is a blocking protocol. During the first phase participating servers begin a transaction and the client carries out its work. This phase is followed by a second voting phase. During voting, the servers first make a firm promise that they are ready to commit the work even in case of their possible unexpected failure. Should a server crash in this phase, it will still recall the aborted transaction after recover and wait for the client to decide on whether it shall be committed or rolled back.

Should a client that has initiated a global transaction crash after all the participating servers gave their promise to be ready to commit, then the servers must wait for a decision. The servers are not allowed to uniliterally decide on the transaction.

A client crash or disconnect from a participant, a server crash or server error during the fist phase of the protocol is uncritical. In most cases, the server will forget about the XA transaction and its work is rolled back. Additionally, the plugin tries to reach out to as many participants as it can to instruct the server to roll back the work immediately. It is not possible to disable this implicit rollback carried out by PECL/mysqlnd_ms in case of errors during the first phase of the protocol. This design decision has been made to keep the implementation simple.

An error during the second phase of the commit protocol can develop into a more severe situation. The servers will not forget about prepared but unfinished transactions in all cases. The plugin will not attempt to solve these cases immediately but waits for optional background garbage collection to ensure progress of the commit protocol. It is assumed that a solution will take significant time as it may include waiting for a participating server to recover from a crash. This time span may be longer than a developer and end user expects when trying to commit a global transaction with <span class="function">mysqlnd_ms_xa_commit. Thus, the function returns with the unfinished global transaction still requiring attention. Please, be warned that at this point, it is not yet clear whether the global transaction will be committed or rolled back later on.

Errors during the second phase can be ignored, handled by yourself or solved by the build-int garbage collection logic. Ignoring them is not recommended as you may experience unfinished global transactions on your servers that block resources virtually indefinetly. Handling the errors requires knowing the participants, checking their state and issueing appropriate SQL commands on them. There are no user API calls to expose this very information. You will have to configure a state store and make the plugin record its actions in it to receive the desired facts.

Please, see the quickstart and related plugin configuration file settings for an example how to configure a state. In addition to configuring a state store, you have to setup some SQL tables. The table definitions are given in the description of the plugin configuration settings.

Setting up and configuring a state store is also a precondition for using the built-in garbage collection for XA transactions that fail during the second commit phase. Recording information about ongoing XA transactions is an unavoidable extra task. The extra task consists of updating the state store after each and every operation that changes the state of the global transaction itself (started, committed, rolled back, errors and aborts), the addition of participants (host, optionally user and password required to connect) and any changes to a participants state. Please note, depending on configuration and your security policies, these recordings may be considered sensitive. It is therefore recommended to restrict access to the state store. Unless the state store itself becomes overloaded, writing the state information may contribute noteworthy to the runtime but should overall be only a minor factor.

It is possible that the effort it takes to implement your own routines for handling XA transactions that failed during the second commit phase exceeds the benefits of using the XA feature of PECL/mysqlnd_ms in the first place. Thus, the manual focussed on using the built-on garbage collection only.

Garbage collection can be triggered manually or automatically in the background. You may want to call <span class="function">mysqlnd_ms_xa_gc immediately after a commit failure to attempt to solve any failed but still open global transactions as soon as possible. You may also decide to disable the automatic background garbage collection, implement your own rule set for invoking the built-in garbage collection and trigger it when desired.

By default the plugin will start the garbage collection with a certain probability in the extensions internal RSHUTDOWN method. The request shutdown is called after your script finished. Whether the garbage collection will be triggered is determined by computing a random value between 1...1000 and comparing it with the configuration setting probability (default: 5). If the setting is greater or equal to the random value, the garbage collection will be triggered.

Once started, the garbage collection acts upon up to max_transactions_per_run (default: 100) global transactions recorded. Records include successfully finished but also unfinished XA transactions. Records for successful transactions are removed and unfinished transactions are attempted to be solved. There are no statistics that help you finding the right balance between keeping garbage collection runs short by limiting the number of transactions considered per run and preventing the garbage collection to fall behind, resulting in many records.

For each failed XA transaction the garbage collection makes max_retries (default: 5) attempts to finish it. After that PECL/mysqlnd_ms gives up. There are two possible reasons for this. Either a participating server crashed and has not become accessible again within max_retries invocations of the garbage collection, or there is a situation that the built-in garbage collection cannot cope with. Likely, the latter would be considered a bug. However, you can manually force more garbage collection runs calling <span class="function">mysqlnd_ms_xa_gc with the appropriate parameter set. Should even those function runs fail to solve the situation, then the problem must be solved by an operator.

The function mysqlnd_ms_get_stats provides some statistics on how many XA transactions have been started, committed, failed or rolled back.

安装/配置

目录

需求

PHP 5.3.6 或更高版本,一些建议使用的功能,需要 PHP 5.4.0 或更高版本。

mysqlnd_ms 主从同步和负载均衡插件,可以支持所有的 PHP 应用程序,并且支持所有的 PHP MySQL 扩展 (mysqli, mysql, PDO_MYSQL)。 所有的 PHP MySQL 扩展必须配置为使用 mysqlnd 并且在 mysqlnd 中使用 mysqlnd_ms

安装

» PECL 扩展未与 PHP 捆绑。

安装此 PECL 扩展相关的信息可在手册中标题为 PECL 扩展的安装章节中找到。更多信息如新的发行版本、下载、源文件、 维护人员信息及变更日志等,都在此处: » https://pecl.php.net/package/mysqlnd_ms

PECL 扩展的 DLL 当前不可用。参见 在 Windows 上构建章节。

运行时配置

这些函数的行为受 php.ini 中的设置影响。

名字 默认 可修改范围 更新日志
mysqlnd_ms.enable 0 PHP_INI_SYSTEM
mysqlnd_ms.force_config_usage 0 PHP_INI_SYSTEM
mysqlnd_ms.ini_file "" PHP_INI_SYSTEM
mysqlnd_ms.config_file "" PHP_INI_SYSTEM
mysqlnd_ms.collect_statistics 0 PHP_INI_SYSTEM
mysqlnd_ms.multi_master 0 PHP_INI_SYSTEM
mysqlnd_ms.disable_rw_split 0 PHP_INI_SYSTEM

这是配置指令的简短说明。

mysqlnd_ms.enable integer
是否启动插件,如果禁用插件将不会嵌入 mysqlnd 库中内部 PROXY 调用的 mysqlnd C API 接口。

mysqlnd_ms.force_config_usage integer
如果启用,插件会在每次尝试 MySQL 连接的时候通过配置文件检查服务器参数。如果存在问题, 连接将被阻塞。

这个参数对于运行中的系统没有什么用处,用于调试配置文件。配置文件的作用分为两个阶段。 首先是 PHP 开始接收 WEB 请求时执行,这时插件会读取并且解析配置文件,在这个较早的阶段 中错误信息可能被陷入循环而不会展现给用户。因此缓存这些错误,并且在 MySQL 连接建立的 时候展现给用户。默认情况下,启动时被缓存的错误会产生一个 E_WARNING 级别的错误。如果设定了 force_config_usage 参数,错误类型会变为 E_RECOVERABLE_ERROR 级别。

可以参考 configuration file debugging notes 说明。

mysqlnd_ms.ini_file string
从 1.4.0 版本已经作废,被 mysqlnd_ms.config_file 替代, 指定插件配置文件。

mysqlnd_ms.config_file string
插件的配置文件名称,mysqlnd_ms.ini_file 从 1.4.0 版本作废。

mysqlnd_ms.collect_statistics integer
启动或者禁用统计信息手机,考虑到性能问题默认是禁用的。统计信息可以使用 mysqlnd_ms_get_stats 获取。

mysqlnd_ms.multi_master integer
是否启动 MySQL multi master 集群,可以参考 supported clusters

mysqlnd_ms.disable_rw_split integer
启动还是禁用读写分离。

控制负载均衡和连接切换是否会基于读写分离。如果禁用读写分离,只有 master 列表 中的服务器会被用于执行语句,所有 slave 列表中的服务器会被忽略。

SQL hint 中 MYSQLND_MS_USE_SLAVE 不会被识别,语句还是会被 发送个 master 执行。

禁用读写分离会影响 <span class="function">mysqlnd_ms_query_is_select 的返回值, 函数将不会再返回在 slave 运行的返回值。

Note: Multiple master servers

设置 mysqlnd_ms.multi_master=1 将允许插件使用多台 master 服务器,否则 master 列表中只能有一个服务器。

可以参考 supported clusters 中的说明

Plugin configuration file (>=1.1.x)

The following documentation applies to PECL/mysqlnd_ms >= 1.1.0-beta. It is not valid for prior versions. For documentation covering earlier versions, see the configuration documentation for mysqlnd_ms 1.0.x and below.

Introduction

Note: Changelog: Feature was added in PECL/mysqlnd_ms 1.1.0-beta

The below description applies to PECL/mysqlnd_ms >= 1.1.0-beta. It is not valid for prior versions.

The plugin uses its own configuration file. The configuration file holds information about the MySQL replication master server, the MySQL replication slave servers, the server pick (load balancing) policy, the failover strategy, and the use of lazy connections.

The plugin loads its configuration file at the beginning of a web request. It is then cached in memory and used for the duration of the web request. This way, there is no need to restart PHP after deploying the configuration file. Configuration file changes will become active almost instantly.

The PHP configuration directive mysqlnd_ms.config_file is used to set the plugins configuration file. Please note, that the PHP configuration directive may not be evaluated for every web request. Therefore, changing the plugins configuration file name or location may require a PHP restart. However, no restart is required to read changes if an already existing plugin configuration file is updated.

Using and parsing JSON is efficient, and using JSON makes it easier to express hierarchical data structures than the standard php.ini format.

示例 #1 Converting a PHP array (hash) into JSON format

Or alternatively, a developer may be more familiar with the PHP <span class="type">array syntax, and prefer it. This example demonstrates how a developer might convert a PHP array to JSON.

<?php
$config = array(
  "myapp" => array(
    "master" => array(
      "master_0" => array(
        "host"   => "localhost",
        "socket" => "/tmp/mysql.sock",
      ),
    ),
    "slave" => array(),
  ),
);

file_put_contents("mysqlnd_ms.ini", json_encode($config, JSON_PRETTY_PRINT));
printf("mysqlnd_ms.ini file created...\n");
printf("Dumping file contents...\n");
printf("%s\n", str_repeat("-", 80));
echo file_get_contents("mysqlnd_ms.ini");
printf("\n%s\n", str_repeat("-", 80));
?>

以上例程会输出:

mysqlnd_ms.ini file created...
Dumping file contents...
--------------------------------------------------------------------------------
{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": [

        ]
    }
}
--------------------------------------------------------------------------------

A plugin configuration file consists of one or more sections. Sections are represented by the top-level object properties of the object encoded in the JSON file. Sections could also be called configuration names.

Applications reference sections by their name. Applications use section names as the host (server) parameter to the various connect methods of the mysqli, mysql and PDO_MYSQL extensions. Upon connect, the mysqlnd plugin compares the hostname with all of the section names from the plugin configuration file. If the hostname and section name match, then the plugin will load the settings for that section.

示例 #2 Using section names example

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.2.27"
            },
            "slave_1": {
                "host": "192.168.2.27",
                "port": 3306
            }
        }
    },
    "localhost": {
        "master": [
            {
                "host": "localhost",
                "socket": "\/path\/to\/mysql.sock"
            }
        ],
        "slave": [
            {
                "host": "192.168.3.24",
                "port": "3305"
            },
            {
                "host": "192.168.3.65",
                "port": "3309"
            }
        ]
    }
}
<?php
/* All of the following connections will be load balanced */
$mysqli = new mysqli("myapp", "username", "password", "database");
$pdo = new PDO('mysql:host=myapp;dbname=database', 'username', 'password');
$mysql = mysql_connect("myapp", "username", "password");

$mysqli = new mysqli("localhost", "username", "password", "database");
?>

Section names are strings. It is valid to use a section name such as 192.168.2.1, 127.0.0.1 or localhost. If, for example, an application connects to localhost and a plugin configuration section localhost exists, the semantics of the connect operation are changed. The application will no longer only use the MySQL server running on the host localhost, but the plugin will start to load balance MySQL queries following the rules from the localhost configuration section. This way you can load balance queries from an application without changing the applications source code. Please keep in mind, that such a configuration may not contribute to overall readability of your applications source code. Using section names that can be mixed up with host names should be seen as a last resort.

Each configuration section contains, at a minimum, a list of master servers and a list of slave servers. The master list is configured with the keyword master, while the slave list is configured with the slave keyword. Failing to provide a slave list will result in a fatal E_ERROR level error, although a slave list may be empty. It is possible to allow no slaves. However, this is only recommended with synchronous clusters, please see also supported clusters. The main part of the documentation focusses on the use of asynchronous MySQL replication clusters.

The master and slave server lists can be optionally indexed by symbolic names for the servers they describe. Alternatively, an array of descriptions for slave and master servers may be used.

示例 #3 List of anonymous slaves

"slave": [
    {
        "host": "192.168.3.24",
        "port": "3305"
    },
    {
        "host": "192.168.3.65",
        "port": "3309"
    }
]

An anonymous server list is encoded by the JSON array type. Optionally, symbolic names may be used for indexing the slave or master servers of a server list, and done so using the JSON object type.

示例 #4 Master list using symbolic names

"master": {
    "master_0": {
        "host": "localhost"
    }
}

It is recommended to index the server lists with symbolic server names. The alias names will be shown in error messages.

The order of servers is preserved and taken into account by mysqlnd_ms. If, for example, you configure round robin load balancing strategy, the first SELECT statement will be executed on the slave that appears first in the slave server list.

A configured server can be described with the host, port, socket, db, user, password and connect_flags. It is mandatory to set the database server host using the host keyword. All other settings are optional.

示例 #5 Keywords to configure a server

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "db_server_host",
                "port": "db_server_port",
                "socket": "db_server_socket",
                "db": "database_resp_schema",
                "user": "user",
                "password": "password",
                "connect_flags": 0
            }
        },
        "slave": {
            "slave_0": {
                "host": "db_server_host",
                "port": "db_server_port",
                "socket": "db_server_socket"
            }
        }
    }
}

If a setting is omitted, the plugin will use the value provided by the user API call used to open a connection. Please, see the using section names example above.

The configuration file format has been changed in version 1.1.0-beta to allow for chained filters. Filters are responsible for filtering the configured list of servers to identify a server for execution of a given statement. Filters are configured with the filter keyword. Filters are executed by mysqlnd_ms in the order of their appearance. Defining filters is optional. A configuration section in the plugins configuration file does not need to have a filters entry.

Filters replace the pick[] setting from prior versions. The new random and roundrobin provide the same functionality.

示例 #6 New roundrobin filter, old functionality

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.78.136",
                "port": "3306"
            },
            "slave_1": {
                "host": "192.168.78.137",
                "port": "3306"
            }
        },
        "filters": {
            "roundrobin": [

            ]
        }
    }
}

The function <span class="function">mysqlnd_ms_set_user_pick_server has been removed. Setting a callback is now done with the user filter. Some filters accept parameters. The user filter requires and accepts a mandatory callback parameter to set the callback previously set through the function <span class="function">mysqlnd_ms_set_user_pick_server.

示例 #7 The user filter replaces <span class="function">mysqlnd_ms_set_user_pick_server

"filters": {
    "user": {
        "callback": "pick_server"
    }
}

The validity of the configuration file is checked both when reading the configuration file and later when establishing a connection. The configuration file is read during PHP request startup. At this early stage a PHP extension may not display error messages properly. In the worst case, no error is shown and a connection attempt fails without an adequate error message. This problem has been cured in version 1.5.0.

示例 #8 Common error message in case of configuration file issues (upto version 1.5.0)

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
?>

以上例程会输出:

Warning: mysqli::mysqli(): (mysqlnd_ms) (mysqlnd_ms) Failed to parse config file [s1.json]. Please, verify the JSON in Command line code

Warning: mysqli::mysqli(): (HY000/2002): php_network_getaddresses: getaddrinfo failed: Name or service not known in Command line code on line 1

Warning: mysqli::query(): Couldn't fetch mysqli in Command line code on line 1

Fatal error: Call to a member function fetch_assoc() on a non-object in Command line code on line 1

Since version 1.5.0 startup errors are additionally buffered and emitted when a connection attempt is made. Use the configuration directive mysqlnd_ms.force_config_usage to set the error type used to display buffered errors. By default an error of type E_WARNING will be emitted.

示例 #9 Improved configuration file validation since 1.5.0

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
?>

以上例程会输出:

Warning: mysqli::mysqli(): (mysqlnd_ms) (mysqlnd_ms) Failed to parse config file [s1.json]. Please, verify the JSON in Command line code on line 1

It can be useful to set mysqlnd_ms.force_config_usage = 1 when debugging potential configuration file errors. This will not only turn the type of buffered startup errors into E_RECOVERABLE_ERROR but also help detecting misspelled section names.

示例 #10 Possibly more precise error due to mysqlnd_ms.force_config_usage=1

mysqlnd_ms.force_config_usage=1
<?php
$mysqli = new mysqli("invalid_section", "username", "password", "database");
?>

以上例程会输出:

Warning: mysqli::mysqli(): (mysqlnd_ms) Exclusive usage of configuration enforced but did not find the correct INI file section (invalid_section) in Command line code on line 1 line 1

Configuration Directives

Here is a short explanation of the configuration directives that can be used.

master array or object
List of MySQL replication master servers. The list of either of the JSON type array to declare an anonymous list of servers or of the JSON type object. Please, see above for examples.

Setting at least one master server is mandatory. The plugin will issue an error of type E_ERROR if the user has failed to provide a master server list for a configuration section. The fatal error may read (mysqlnd_ms) Section [master] doesn't exist for host [name_of_a_config_section] in %s on line %d.

A server is described with the host, port, socket, db, user, password and connect_flags. It is mandatory to provide at a value for host. If any of the other values is not given, it will be taken from the user API connect call, please, see also: using section names example.

Table of server configuration keywords.

Keyword Description Version
host Database server host. This is a mandatory setting. Failing to provide, will cause an error of type E_RECOVERABLE_ERROR when the plugin tries to connect to the server. The error message may read (mysqlnd_ms) Cannot find [host] in [%s] section in config in %s on line %d. Since 1.1.0.
port Database server TCP/IP port. Since 1.1.0.
socket Database server Unix domain socket. Since 1.1.0.
db Database (schemata). Since 1.1.0.
user MySQL database user. Since 1.1.0.
password MySQL database user password. Since 1.1.0.
connect_flags Connection flags. Since 1.1.0.

The plugin supports using only one master server. An experimental setting exists to enable multi-master support. The details are not documented. The setting is meant for development only.

slave array or object
List of one or more MySQL replication slave servers. The syntax is identical to setting master servers, please, see master above for details.

The plugin supports using one or more slave servers.

Setting a list of slave servers is mandatory. The plugin will report an error of the type E_ERROR if slave is not given for a configuration section. The fatal error message may read (mysqlnd_ms) Section [slave] doesn't exist for host [%s] in %s on line %d. Note, that it is valid to use an empty slave server list. The error has been introduced to prevent accidently setting no slaves by forgetting about the slave setting. A master-only setup is still possible using an empty slave server list.

If an empty slave list is configured and an attempt is made to execute a statement on a slave the plugin may emit a warning like mysqlnd_ms) Couldn't find the appropriate slave connection. 0 slaves to choose from. upon statement execution. It is possible that another warning follows such as (mysqlnd_ms) No connection selected by the last filter.

global_transaction_id_injection array or object
Global transaction identifier configuration related to both the use of the server built-in global transaction ID feature and the client-side emulation.

Keyword Description Version
fetch_last_gtid

SQL statement for accessing the latest global transaction identifier. The SQL statement is run if the plugin needs to know the most recent global transaction identifier. This can be the case, for example, when checking MySQL Replication slave status. Also used with mysqlnd_ms_get_last_gtid.

Since 1.2.0.
check_for_gtid

SQL statement for checking if a replica has replicated all transactions up to and including ones searched for. The SQL statement is run when searching for replicas which can offer a higher level of consistency than eventual consistency. The statement must contain a placeholder #GTID which is to be replaced with the global transaction identifier searched for by the plugin. Please, check the quickstart for examples.

Since 1.2.0.
report_errors

Whether to emit an error of type warning if an issue occurs while executing any of the configured SQL statements.

Since 1.2.0.
on_commit

Client-side global transaction ID emulation only. SQL statement to run when a transaction finished to update the global transaction identifier sequence number on the master. Please, see the quickstart for examples.

Since 1.2.0.
wait_for_gtid_timeout

Instructs the plugin to wait up to wait_for_gtid_timeout seconds for a slave to catch up when searching for slaves that can deliver session consistency. The setting limits the time spend for polling the slave status. If polling the status takes very long, the total clock time spend waiting may exceed wait_for_gtid_timeout. The plugin calls sleep(1) to sleep one second between each two polls.

The setting can be used both with the plugins client-side emulation and the server-side global transaction identifier feature of MySQL 5.6.

Waiting for a slave to replicate a certain GTID needed for session consistency also means throttling the client. By throttling the client the write load on the master is reduced indirectly. A primary copy based replication system, such as MySQL Replication, is given more time to reach a consistent state. This can be desired, for example, to increase the number of data copies for high availability considerations or to prevent the master from being overloaded.

Since 1.4.0.

fabric object
MySQL Fabric related settings. If the plugin is used together with MySQL Fabric, then the plugins configuration file no longer contains lists of MySQL servers. Instead, the plugin will ask MySQL Fabric which list of servers to use to perform a certain task.

A minimum plugin configuration for use with MySQL Fabric contains a list of one or more MySQL Fabric hosts that the plugin can query. If more than one MySQL Fabric host is configured, the plugin will use a roundrobin strategy to choose among them. Other strategies are currently not available.

示例 #11 Minimum pluging configuration for use with MySQL Fabric

{
    "myapp": {
        "fabric": {
            "hosts": [
                {
                    "host" : "127.0.0.1",
                    "port" : 8080
                }
            ]
        }
    }
}

Each MySQL Fabric host is described using a JSON object with the following members.

Keyword Description Version
host Host name of the MySQL Fabric host. Since 1.6.0.
port The TCP/IP port on which the MySQL Fabric host listens for remote procedure calls sent by clients such as the plugin. Since 1.6.0.

The plugin is using PHP streams to communicate with MySQL Fabric through XML RPC over HTTP. By default no timeouts are set for the network communication. Thus, the plugin defaults to PHP stream default timeouts. Those defaults are out of control of the plugin itself.

An optional timeout value can be set to overrule the PHP streams default timeout setting. Setting the timeout in the plugins configuration file has the same effect as setting a timeout for a PHP user space HTTP connection established through PHP streams.

The plugins Fabric timeout value unit is seconds. The allowed value range is from 0 to 65535. The setting exists since version 1.6.

示例 #12 Optional timeout for communication with Fabric

{
    "myapp": {
        "fabric": {
            "hosts": [
                {
                    "host" : "127.0.0.1",
                    "port" : 8080
                }
            ],
            "timeout": 2
        }
    }
}

Transaction stickiness and MySQL Fabric logic can collide. The stickiness option disables switching between servers for the duration of a transaction. When using Fabric and sharding the user may (erroneously) start a local transaction on one share and then attempt to switch to a different shard using either mysqlnd_ms_fabric_select_shard or mysqlnd_ms_fabric_select_global. In this case, the plugin will not reject the request to switch servers in the middle of a transaction but allow the user to switch to another server regardless of the transaction stickiness setting used. It is clearly a user error to write such code.

If transaction stickiness is enabled and you would like to get an error of type warning when calling mysqlnd_ms_fabric_select_shard or mysqlnd_ms_fabric_select_global, set the boolean flag trx_warn_server_list_changes.

示例 #13 Warnings about the violation of transaction boundaries

{
    "myapp": {
        "fabric": {
            "hosts": [
                {
                    "host" : "127.0.0.1",
                    "port" : 8080
                }
            ],
            "trx_warn_serverlist_changes": 1
        },
        "trx_stickiness": "on"
    }
}
<?php
$link = new mysqli("myapp", "root", "", "test");
/*
  For the demo the call may fail.
  Failed or not we get into the state
  needed for the example.
*/
@mysqlnd_ms_fabric_select_global($link, 1);
$link->begin_transaction();
@$link->query("DROP TABLE IF EXISTS test");
/*
  Switching servers/shards is a mistake due to open
  local transaction!
*/
mysqlnd_ms_select_global($link, 1);
?>

以上例程会输出:

PHP Warning: mysqlnd_ms_fabric_select_global(): (mysqlnd_ms) Fabric server exchange in the middle of a transaction in %s on line %d

Please, consider the feature experimental. Changes to syntax and semantics may happen.

filters object
List of filters. A filter is responsible to filter the list of available servers for executing a given statement. Filters can be chained. The random and roundrobin filter replace the pick[] directive used in prior version to select a load balancing policy. The user filter replaces the <span class="function">mysqlnd_ms_set_user_pick_server function.

Filters may accept parameters to refine their actions.

If no load balancing policy is set, the plugin will default to random_once. The random_once policy picks a random slave server when running the first read-only statement. The slave server will be used for all read-only statements until the PHP script execution ends. No load balancing policy is set and thus, defaulting takes place, if neither the random nor the roundrobin are part of a configuration section.

If a filter chain is configured so that a filter which output no more than once server is used as input for a filter which should be given more than one server as input, the plugin may emit a warning upon opening a connection. The warning may read: (mysqlnd_ms) Error while creating filter '%s' . Non-multi filter '%s' already created. Stopping in %s on line %d. Furthermore, an error of the error code 2000, the sql state HY000 and an error message similar to the warning may be set on the connection handle.

示例 #14 Invalid filter sequence

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.78.136",
                "port": "3306"
            }
        },
        "filters": [
            "roundrobin",
            "random"
        ]
    }
}
<?php
$link = new mysqli("myapp", "root", "", "test");
printf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
$link->query("SELECT 1 FROM DUAL");
?>

以上例程会输出:

PHP Warning:  mysqli::mysqli(): (HY000/2000): (mysqlnd_ms) Error while creating filter 'random' . Non-multi filter 'roundrobin' already created. Stopping in filter_warning.php on line 1
[2000] (mysqlnd_ms) Error while creating filter 'random' . Non-multi filter 'roundrobin' already created. Stopping
PHP Warning:  mysqli::query(): Couldn't fetch mysqli in filter_warning.php on line 3

Filter: random object
The random filter features the random and random once load balancing policies, set through the pick[] directive in older versions.

The random policy will pick a random server whenever a read-only statement is to be executed. The random once strategy picks a random slave server once and continues using the slave for the rest of the PHP web request. Random once is a default, if load balancing is not configured through a filter.

If the random filter is not given any arguments, it stands for random load balancing policy.

示例 #15 Random load balancing with random filter

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.78.136",
                "port": "3306"
            },
            "slave_1": {
                "host": "192.168.78.137",
                "port": "3306"
            }
        },
        "filters": [
            "random"
        ]
    }
}

Optionally, the sticky argument can be passed to the filter. If the parameter sticky is set to the string 1, the filter follows the random once load balancing strategy.

示例 #16 Random once load balancing with random filter

{
    "filters": {
        "random": {
            "sticky": "1"
        }
    }
}

Both the random and roundrobin filters support setting a priority, a weight for a server, since PECL/mysqlnd_ms 1.4.0. If the weight argument is passed to the filter, it must assign a weight for all servers. Servers must be given an alias name in the slave respectively master server lists. The alias must be used to reference servers for assigning a priority with weight.

示例 #17 Referencing error

[E_RECOVERABLE_ERROR] mysqli_real_connect(): (mysqlnd_ms) Unknown server 'slave3' in 'random' filter configuration. Stopping in %s on line %d

Using a wrong alias name with weight may result in an error similar to the shown above.

If weight is omitted, the default weight of all servers is one.

示例 #18 Assigning a weight for load balancing

{
   "myapp": {
       "master": {
           "master1":{
               "host":"localhost",
               "socket":"\/var\/run\/mysql\/mysql.sock"
           }
       },
       "slave": {
           "slave1": {
               "host":"192.168.2.28",
               "port":3306
           },
           "slave2": {
               "host":"192.168.2.29",
               "port":3306
           },
           "slave3": {
               "host":"192.0.43.10",
               "port":3306
           },
       },
       "filters": {
           "random": {
               "weights": {
                   "slave1":8,
                   "slave2":4,
                   "slave3":1,
                   "master1":1
               }
           }
       }
   }
}

At the average a server assigned a weight of two will be selected twice as often as a server assigned a weight of one. Different weights can be assigned to reflect differently sized machines, to prefer co-located slaves which have a low network latency or, to configure a standby failover server. In the latter case, you may want to assign the standby server a very low weight in relation to the other servers. For example, given the configuration above slave3 will get only some eight percent of the requests in the average. As long as slave1 and slave2 are running, it will be used sparsely, similar to a standby failover server. Upon failure of slave1 and slave2, the usage of slave3 increases. Please, check the notes on failover before using weight this way.

Valid weight values range from 1 to 65535.

Unknown arguments are ignored by the filter. No warning or error is given.

The filter expects one or more servers as input. Outputs one server. A filter sequence such as random, roundrobin may cause a warning and an error message to be set on the connection handle when executing a statement.

List of filter arguments.

Keyword Description Version
sticky Enables or disabled random once load balancing policy. See above. Since 1.2.0.
weight Assigns a load balancing weight/priority to a server. Please, see above for a description. Since 1.4.0.

Filter: roundrobin object
If using the roundrobin filter, the plugin iterates over the list of configured slave servers to pick a server for statement execution. If the plugin reaches the end of the list, it wraps around to the beginning of the list and picks the first configured slave server.

示例 #19 roundrobin filter

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.78.136",
                "port": "3306"
            }
        },
        "filters": [
            "roundrobin"
        ]
    }
}

Expects one or more servers as input. Outputs one server. A filter sequence such as roundrobin, random may cause a warning and an error message to be set on the connection handle when executing a statement.

List of filter arguments.

Keyword Description Version
weight Assigns a load balancing weight/priority to a server. Please, find a description above. Since 1.4.0.

Filter: user object
The user replaces <span class="function">mysqlnd_ms_set_user_pick_server function, which was removed in 1.1.0-beta. The filter sets a callback for user-defined read/write splitting and server selection.

The plugins built-in read/write query split mechanism decisions can be overwritten in two ways. The easiest way is to prepend a query string with the SQL hints MYSQLND_MS_MASTER_SWITCH, MYSQLND_MS_SLAVE_SWITCH or MYSQLND_MS_LAST_USED_SWITCH. Using SQL hints one can control, for example, whether a query shall be send to the MySQL replication master server or one of the slave servers. By help of SQL hints it is not possible to pick a certain slave server for query execution.

Full control on server selection can be gained using a callback function. Use of a callback is recommended to expert users only because the callback has to cover all cases otherwise handled by the plugin.

The plugin will invoke the callback function for selecting a server from the lists of configured master and slave servers. The callback function inspects the query to run and picks a server for query execution by returning the hosts URI, as found in the master and slave list.

If the lazy connections are enabled and the callback chooses a slave server for which no connection has been established so far and establishing the connection to the slave fails, the plugin will return an error upon the next action on the failed connection, for example, when running a query. It is the responsibility of the application developer to handle the error. For example, the application can re-run the query to trigger a new server selection and callback invocation. If so, the callback must make sure to select a different slave, or check slave availability, before returning to the plugin to prevent an endless loop.

示例 #20 Setting a callback

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.78.136",
                "port": "3306"
            }
        },
        "filters": {
            "user": {
                "callback": "pick_server"
            }
        }
    }
}

The callback is supposed to return a host to run the query on. The host URI is to be taken from the master and slave connection lists passed to the callback function. If callback returns a value neither found in the master nor in the slave connection lists the plugin will emit an error of the type E_RECOVERABLE_ERROR The error may read like (mysqlnd_ms) User filter callback has returned an unknown server. The server 'server that is not in master or slave list' can neither be found in the master list nor in the slave list. If the application catches the error to ignore it, follow up errors may be set on the connection handle, for example, (mysqlnd_ms) No connection selected by the last filter with the error code 2000 and the sqlstate HY000. Furthermore a warning may be emitted.

Referencing a non-existing function as a callback will result in any error of the type E_RECOVERABLE_ERROR whenever the plugin tries to callback function. The error message may reads like: (mysqlnd_ms) Specified callback (pick_server) is not a valid callback. If the application catches the error to ignore it, follow up errors may be set on the connection handle, for example, (mysqlnd_ms) Specified callback (pick_server) is not a valid callback with the error code 2000 and the sqlstate HY000. Furthermore a warning may be emitted.

The following parameters are passed from the plugin to the callback.

Parameter Description Version
connected_host

URI of the currently connected database server.

Since 1.1.0.
query

Query string of the statement for which a server needs to be picked.

Since 1.1.0.
masters

List of master servers to choose from. Note, that the list of master servers may not be identical to the list of configured master servers if the filter is not the first in the filter chain. Previously run filters may have reduced the master list already.

Since 1.1.0.
slaves

List of slave servers to choose from. Note, that the list of master servers may not be identical to the list of configured master servers if the filter is not the first in the filter chain. Previously run filters may have reduced the master list already.

Since 1.1.0.
last_used_connection

URI of the server of the connection used to execute the previous statement on.

Since 1.1.0.
in_transaction

Boolean flag indicating whether the statement is part of an open transaction. If autocommit mode is turned off, this will be set to true. Otherwise it is set to false.

Transaction detection is based on monitoring the mysqlnd library call set_autocommit. Monitoring is not possible before PHP 5.4.0. Please, see connection pooling and switching concepts discussion for further details.

Since 1.1.0.

示例 #21 Using a callback

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.2.27",
                "port": "3306"
            },
            "slave_1": {
                "host": "192.168.78.136",
                "port": "3306"
            }
        },
        "filters": {
            "user": {
                "callback": "pick_server"
            }
        }
    }
}
<?php
function pick_server($connected, $query, $masters, $slaves, $last_used_connection, $in_transaction)
{
 static $slave_idx = 0;
 static $num_slaves = NULL;
 if (is_null($num_slaves))
  $num_slaves = count($slaves);

 /* default: fallback to the plugins build-in logic */
 $ret = NULL;

 printf("User has connected to '%s'...\n", $connected);
 printf("... deciding where to run '%s'\n", $query);

 $where = mysqlnd_ms_query_is_select($query);
 switch ($where)
 {
  case MYSQLND_MS_QUERY_USE_MASTER:
   printf("... using master\n");
   $ret = $masters[0];
   break;
  case MYSQLND_MS_QUERY_USE_SLAVE:
   /* SELECT or SQL hint for using slave */
   if (stristr($query, "FROM table_on_slave_a_only"))
   {
    /* a table which is only on the first configured slave  */
    printf("... access to table available only on slave A detected\n");
    $ret = $slaves[0];
   }
   else
   {
    /* round robin */
    printf("... some read-only query for a slave\n");
    $ret = $slaves[$slave_idx++ % $num_slaves];
   }
   break;
  case MYSQLND_MS_QUERY_LAST_USED:
   printf("... using last used server\n");
   $ret = $last_used_connection;
   break;
 }

 printf("... ret = '%s'\n", $ret);
 return $ret;
}

$mysqli = new mysqli("myapp", "root", "", "test");

if (!($res = $mysqli->query("SELECT 1 FROM DUAL")))
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
else
 $res->close();

if (!($res = $mysqli->query("SELECT 2 FROM DUAL")))
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
else
 $res->close();


if (!($res = $mysqli->query("SELECT * FROM table_on_slave_a_only")))
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
else
 $res->close();

$mysqli->close();
?>

以上例程会输出:

User has connected to 'myapp'...
... deciding where to run 'SELECT 1 FROM DUAL'
... some read-only query for a slave
... ret = 'tcp://192.168.2.27:3306'
User has connected to 'myapp'...
... deciding where to run 'SELECT 2 FROM DUAL'
... some read-only query for a slave
... ret = 'tcp://192.168.78.136:3306'
User has connected to 'myapp'...
... deciding where to run 'SELECT * FROM table_on_slave_a_only'
... access to table available only on slave A detected
... ret = 'tcp://192.168.2.27:3306'

Filter: user_multi object
The user_multi differs from the user only in one aspect. Otherwise, their syntax is identical. The user filter must pick and return exactly one node for statement execution. A filter chain usually ends with a filter that emits only one node. The filter chain shall reduce the list of candidates for statement execution down to one. This, only one node left, is the case after the user filter has been run.

The user_multi filter is a multi filter. It returns a list of slave and a list of master servers. This list needs further filtering to identify exactly one node for statement execution. A multi filter is typically placed at the top of the filter chain. The quality_of_service filter is another example of a multi filter.

The return value of the callback set for user_multi must be an array with two elements. The first element holds a list of selected master servers. The second element contains a list of selected slave servers. The lists shall contain the keys of the slave and master servers as found in the slave and master lists passed to the callback. The below example returns random master and slave lists extracted from the functions input.

示例 #22 Returning random masters and slaves

<?php
function pick_server($connected, $query, $masters, $slaves, $last_used_connection, $in_transaction)
{
  $picked_masters = array()
  foreach ($masters as $key => $value) {
    if (mt_rand(0, 2) > 1)
      $picked_masters[] = $key;
  }
  $picked_slaves = array()
  foreach ($slaves as $key => $value) {
    if (mt_rand(0, 2) > 1)
      $picked_slaves[] = $key;
  }
  return array($picked_masters, $picked_slaves);
}
?>

The plugin will issue an error of type E_RECOVERABLE if the callback fails to return a server list. The error may read (mysqlnd_ms) User multi filter callback has not returned a list of servers to use. The callback must return an array in %s on line %d. In case the server list is not empty but has invalid servers key/ids in it, an error of type E_RECOVERABLE will the thrown with an error message like (mysqlnd_ms) User multi filter callback has returned an invalid list of servers to use. Server id is negative in %s on line %d, or similar.

Whether an error is emitted in case of an empty slave or master list depends on the configuration. If an empty master list is returned for a write operation, it is likely that the plugin will emit a warning that may read (mysqlnd_ms) Couldn't find the appropriate master connection. 0 masters to choose from. Something is wrong in %s on line %d. Typically a follow up error of type E_ERROR will happen. In case of a read operation and an empty slave list the behavior depends on the fail over configuration. If fail over to master is enabled, no error should appear. If fail over to master is deactivated the plugin will emit a warning that may read (mysqlnd_ms) Couldn't find the appropriate slave connection. 0 slaves to choose from. Something is wrong in %s on line %d.

Filter: node_groups object
The node_groups filter lets you group cluster nodes and query selected groups, for example, to support data partitioning. Data partitioning can be required for manual sharding, primary copy based clusters running multiple masters, or to avoid hot spots in update everywhere clusters that have no built-in partitioning. The filter is a multi filter which returns zero, one or multiple of its input servers. Thus, it must be followed by other filters to reduce the number of candidates down to one for statement execution.

Keyword Description Version
user defined node group name

One or more node groups must be defined. A node group can have an arbitrary user defined name. The name is used in combination with a SQL hint to restrict query execution to the nodes listed for the node group. To run a query on any of the servers of a node group, the query must begin with the SQL hint /*user defined node group name*/. Please note, no white space is allowed around user defined node group name. Because user defined node group name is used as-is as part of a SQL hint, you should choose the name that is compliant with the SQL language.

Each node group entry must contain a list of master servers. Additional slave servers are allowed. Failing to provide a list of master for a node group name_of_group may cause an error of type E_RECOVERABLE_ERROR like (mysqlnd_ms) No masters configured in node group 'name_of_group' for 'node_groups' filter.

The list of master and slave servers must reference corresponding entries in the global master respectively slave server list. Referencing an unknown server in either of the both server lists may cause an E_RECOVERABLE_ERROR error like (mysqlnd_ms) Unknown master 'server_alias_name' (section 'name_of_group') in 'node_groups' filter configuration.

示例 #23 Manual partitioning

{
  "myapp": {
       "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.2.28",
                "port": 3306
            },
            "slave_1": {
                "host": "127.0.0.1",
                "port": 3311
            }
        },
        "filters": {
            "node_groups": {
                "Partition_A" : {
                    "master": ["master_0"],
                    "slave": ["slave_0"]
                }
            },
           "roundrobin": []
        }
    }
}

Please note, if a filter chain generates an empty slave list and the PHP configuration directive mysqlnd_ms.multi_master=0 is used, the plugin may emit a warning.

Since 1.5.0.

Filter: quality_of_service object
The quality_of_service identifies cluster nodes capable of delivering a certain quality of service. It is a multi filter which returns zero, one or multiple of its input servers. Thus, it must be followed by other filters to reduce the number of candidates down to one for statement execution.

The quality_of_service filter has been introduced in 1.2.0-alpha. In the 1.2 series the filters focus is on the consistency aspect of service quality. Different types of clusters offer different default data consistencies. For example, an asynchronous MySQL replication slave offers eventual consistency. The slave may not be able to deliver requested data because it has not replicated the write, it may serve stale database because its lagging behind or it may serve current information. Often, this is acceptable. In some cases higher consistency levels are needed for the application to work correct. In those cases, the quality_of_service can filter out cluster nodes which cannot deliver the necessary quality of service.

The quality_of_service filter can be replaced or created at runtime. A successful call to mysqlnd_ms_set_qos removes all existing qos filter entries from the filter list and installs a new one at the very beginning. All settings that can be made through mysqlnd_ms_set_qos can also be in the plugins configuration file. However, use of the function is by far the most common use case. Instead of setting session consistency and strong consistency service levels in the plugins configuration file it is recommended to define only masters and no slaves. Both service levels will force the use of masters only. Using an empty slave list shortens the configuration file, thus improving readability. The only service level for which there is a case of defining in the plugins configuration file is the combination of eventual consistency and maximum slave lag.

Keyword Description Version
eventual_consistency

Request eventual consistency. Allows the use of all master and slave servers. Data returned may or may not be current.

Eventual consistency accepts an optional age parameter. If age is given the plugin considers only slaves for reading for which MySQL replication reports a slave lag less or equal to age. The replication lag is measure using SHOW SLAVE STATUS. If the plugin fails to fetch the replication lag, the slave tested is skipped. Implementation details and tips are given in the quality of service concepts section.

Please note, if a filter chain generates an empty slave list and the PHP configuration directive mysqlnd_ms.multi_master=0 is used, the plugin may emit a warning.

示例 #24 Global limit on slave lag

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.2.27",
                "port": "3306"
            },
            "slave_1": {
                "host": "192.168.78.136",
                "port": "3306"
            }
        },
        "filters": {
            "quality_of_service": {
                "eventual_consistency": {
                    "age":123
                }
            }
        }
    }
}
Since 1.2.0.
session_consistency

Request session consistency (read your writes). Allows use of all masters and all slaves which are in sync with the master. If no further parameters are given slaves are filtered out as there is no reliable way to test if a slave has caught up to the master or is lagging behind. Please note, if a filter chain generates an empty slave list and the PHP configuration directive mysqlnd_ms.multi_master=0 is used, the plugin may emit a warning.

Session consistency temporarily requested using mysqlnd_ms_set_qos is a valuable alternative to using master_on_write. master_on_write is likely to send more statements to the master than needed. The application may be able to continue operation at a lower consistency level after it has done some critical reads.

Since 1.1.0.
strong_consistency

Request strong consistency. Only masters will be used.

Since 1.2.0.

failover Up to and including 1.3.x: string. Since 1.4.0: object.
Failover policy. Supported policies: disabled (default), master, loop_before_master (Since 1.4.0).

If no failover policy is set, the plugin will not do any automatic failover (failover=disabled). Whenever the plugin fails to connect a server it will emit a warning and set the connections error code and message. Thereafter it is up to the application to handle the error and, for example, resent the last statement to trigger the selection of another server.

Please note, the automatic failover logic is applied when opening connections only. Once a connection has been opened no automatic attempts are made to reopen it in case of an error. If, for example, the server a connection is connected to is shut down and the user attempts to run a statement on the connection, no automatic failover will be tried. Instead, an error will be reported.

If using failover=master the plugin will implicitly failover to a master, if available. Please check the concepts documentation to learn about potential pitfalls and risks of using failover=master.

示例 #25 Optional master failover when failing to connect to slave (PECL/mysqlnd_ms \< 1.4.0)

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.78.136",
                "port": "3306"
            }
        },
        "failover": "master"
    }
}

Since PECL/mysqlnd_ms 1.4.0 the failover configuration keyword refers to an object.

示例 #26 New syntax since 1.4.0

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.78.136",
                "port": "3306"
            }
        },
        "failover": {"strategy": "master" }
    }
}
Keyword Description Version
strategy

Failover policy. Possible values: disabled (default), master, loop_before_master

A value of disabled disables automatic failover.

Setting master instructs the plugin to try to connect to a master in case of a slave connection error. If the master connection attempt fails, the plugin exists the failover loop and returns an error to the user.

If using loop_before_master and a slave request is made, the plugin tries to connect to other slaves before failing over to a master. If multiple master are given and multi master is enabled, the plugin also loops over the list of masters and attempts to connect before returning an error to the user.

Since 1.4.0.
remember_failed

Remember failures for the duration of a web request. Default: false.

If set to true the plugin will remember failed hosts and skip the hosts in all future load balancing made for the duration of the current web request.

Since 1.4.0. The feature is only available together with the random and roundrobin load balancing filter. Use of the setting is recommended.
max_retries

Maximum number of connection attempts before skipping host. Default: 0 (no limit).

The setting is used to prevent hosts from being dropped of the host list upon the first failure. If set to n > 0, the plugin will keep the node in the node list even after a failed connection attempt. The node will not be removed immediately from the slave respectively master lists after the first connection failure but instead be tried to connect to up to n times in future load balancing rounds before being removed.

Since 1.4.0. The feature is only available together with the random and roundrobin load balancing filter.

Setting failover to any other value but disabled, master or loop_before_master will not emit any warning or error.

lazy_connections bool
Controls the use of lazy connections. Lazy connections are connections which are not opened before the client sends the first connection. Lazy connections are a default.

It is strongly recommended to use lazy connections. Lazy connections help to keep the number of open connections low. If you disable lazy connections and, for example, configure one MySQL replication master server and two MySQL replication slaves, the plugin will open three connections upon the first call to a connect function although the application might use the master connection only.

Lazy connections bare a risk if you make heavy use of actions which change the state of a connection. The plugin does not dispatch all state changing actions to all connections from the connection pool. The few dispatched actions are applied to already opened connections only. Lazy connections opened in the future are not affected. Only some settings are "remembered" and applied when lazy connections are opened.

示例 #27 Disabling lazy connection

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.78.136",
                "port": "3306"
            }
        },
        "lazy_connections": 0
    }
}

Please, see also server_charset to overcome potential problems with string escaping and servers using different default charsets.

server_charset string
The setting has been introduced in 1.4.0. It is recommended to set it if using lazy connections.

The server_charset setting serves two purposes. It acts as a fallback charset to be used for string escaping done before a connection has been established and it helps to avoid escaping pitfalls in heterogeneous environments which servers using different default charsets.

String escaping takes a connections charset into account. String escaping is not possible before a connection has been opened and the connections charset is known. The use of lazy connections delays the actual opening of connections until a statement is send.

An application using lazy connections may attempt to escape a string before sending a statement. In fact, this should be a common case as the statement string may contain the string that is to be escaped. However, due to the lazy connection feature no connection has been opened yet and escaping fails. The plugin may report an error of the type E_WARNING and a message like (mysqlnd_ms) string escaping doesn't work without established connection. Possible solution is to add server_charset to your configuration to inform you of the pitfall.

Setting server_charset makes the plugin use the given charset for string escaping done on lazy connection handles before establishing a network connection to MySQL. Furthermore, the plugin will enforce the use of the charset when the connection is established.

Enforcing the use of the configured charset used for escaping is done to prevent tapping into the pitfall of using a different charset for escaping than used later for the connection. This has the additional benefit of removing the need to align the charset configuration of all servers used. No matter what the default charset on any of the servers is, the plugin will set the configured one as a default.

The plugin does not stop the user from changing the charset at any time using the set_charset call or corresponding SQL statements. Please, note that the use of SQL is not recommended as it cannot be monitored by the plugin. The user can, for example, change the charset on a lazy connection handle after escaping a string and before the actual connection is opened. The charset set by the user will be used for any subsequent escaping before the connection is established. The connection will be established using the configured charset, no matter what the server charset is or what the user has set before. Once a connection has been opened, set_charset is of no meaning anymore.

示例 #28 String escaping on a lazy connection handle

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.78.136",
                "port": "3306"
            }
        },
        "lazy_connections": 1,
        "server_charset" : "utf8"
    }
}
<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
$mysqli->real_escape("this will be escaped using the server_charset setting - utf8");
$mysqli->set_charset("latin1");
$mysqli->real_escape("this will be escaped using latin1");
/* server_charset implicitly set - utf8 connection */
$mysqli->query("SELECT 'This connection will be set to server_charset upon establishing' AS _msg FROM DUAL");
/* latin1 used from now on */
$mysqli->set_charset("latin1");
?>

master_on_write bool
If set, the plugin will use the master server only after the first statement has been executed on the master. Applications can still send statements to the slaves using SQL hints to overrule the automatic decision.

The setting may help with replication lag. If an application runs an INSERT the plugin will, by default, use the master to execute all following statements, including SELECT statements. This helps to avoid problems with reads from slaves which have not replicated the INSERT yet.

示例 #29 Master on write for consistent reads

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.78.136",
                "port": "3306"
            }
        },
        "master_on_write": 1
    }
}

Please, note the quality_of_service filter introduced in version 1.2.0-alpha. It gives finer control, for example, for achieving read-your-writes and, it offers additional functionality introducing service levels.

All transaction stickiness settings, including trx_stickiness=on, are overruled by master_on_write=1.

trx_stickiness string
Transaction stickiness policy. Supported policies: disabled (default), master.

The setting requires 5.4.0 or newer. If used with PHP older than 5.4.0, the plugin will emit a warning like (mysqlnd_ms) trx_stickiness strategy is not supported before PHP 5.3.99.

If no transaction stickiness policy is set or, if setting trx_stickiness=disabled, the plugin is not transaction aware. Thus, the plugin may load balance connections and switch connections in the middle of a transaction. The plugin is not transaction safe. SQL hints must be used avoid connection switches during a transaction.

As of PHP 5.4.0 the mysqlnd library allows the plugin to monitor the autocommit mode set by calls to the libraries set_autocommit() function. If setting set_stickiness=master and autocommit gets disabled by a PHP MySQL extension invoking the mysqlnd library internal function call set_autocommit(), the plugin is made aware of the begin of a transaction. Then, the plugin stops load balancing and directs all statements to the master server until autocommit is enabled. Thus, no SQL hints are required.

An example of a PHP MySQL API function calling the mysqlnd library internal function call set_autocommit() is <span class="function">mysqli_autocommit.

Although setting trx_stickiness=master, the plugin cannot be made aware of autocommit mode changes caused by SQL statements such as SET AUTOCOMMIT=0 or BEGIN.

As of PHP 5.5.0, the mysqlnd library features additional C API calls to control transactions. The level of control matches the one offered by SQL statements. The mysqli API has been modified to use these calls. Since version 1.5.0, PECL/mysqlnd_ms can monitor not only <span class="function">mysqli_autocommit, but also <span class="function">mysqli_begin, <span class="function">mysqli_commit and <span class="function">mysqli_rollback to detect transaction boundaries and stop load balancing for the duration of a transaction.

示例 #30 Using master to execute transactions

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.78.136",
                "port": "3306"
            }
        },
        "trx_stickiness": "master"
    }
}

Since version 1.5.0 automatic and silent failover is disabled for the duration of a transaction. If the boundaries of a transaction have been properly detected, transaction stickiness is enabled and a server fails, the plugin will not attempt to fail over to the next server, if any, regardless of the failover policy configured. The user must handle the error manually. Depending on the configuration, the plugin may emit an error of type E_WARNING reading like (mysqlnd_ms) Automatic failover is not permitted in the middle of a transaction. This error may then be overwritten by follow up errors such as (mysqlnd_ms) No connection selected by the last filter. Those errors will be generated by the failing query function.

示例 #31 No automatic failover, error handling pitfall

<?php
/* assumption: automatic failover configured */
$mysqli = new mysqli("myapp", "username", "password", "database");

/* sets plugin internal state in_trx = 1 */
$mysqli->autocommit(false);

/* assumption: server fails */
if (!($res = $mysqli->query("SELECT 'Assume this query fails' AS _msg FROM DUAL"))) {
 /* handle failure of transaction, plugin internal state is still in_trx = 1 */
 printf("[%d] %s", $mysqli->errno, $mysqli->error);
 /*
  If using autocommit() based transaction detection it is a
  MUST to call autocommit(true). Otherwise the plugin assumes
  the current transaction continues and connection
  changes remain forbidden.
 */
 $mysqli->autocommit(true);
 /* Likewise, you'll want to start a new transaction */
 $mysqli->autocommit(false);
}
/* latin1 used from now on */
$mysqli->set_charset("latin1");
?>

If a server fails in the middle of a transaction the plugin continues to refuse to switch connections until the current transaction has been finished. Recall that the plugin monitors API calls to detect transaction boundaries. Thus, you have to, for example, enable auto commit mode to end the current transaction before the plugin continues load balancing and switches the server. Likewise, you will want to start a new transaction immediately thereafter and disable auto commit mode again.

Not handling failed queries and not ending a failed transaction using API calls may cause all following commands emit errors such as Commands out of sync; you can't run this command now. Thus, it is important to handle all errors.

transient_error object
The setting has been introduced in 1.6.0.

A database cluster node may reply a transient error to a client. The client can then repeat the operation on the same node, fail over to a different node or abort the operation. Per definition is it safe for a client to retry the same operation on the same node before giving up.

PECL/mysqlnd_ms can perform the retry loop on behalf of the application. By configuring transient_error the plugin can be instructed to repeat operations failing with a certain error code for a certain maximum number of times with a pause between the retries. If the transient error disappears during loop execution, it is hidden from the application. Otherwise, the error is forwarded to the application by the end of the loop.

示例 #32 Retry loop for transient errors

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.78.136",
                "port": "3306"
            }
       },
       "transient_error": {
          "mysql_error_codes": [
            1297
          ],
          "max_retries": 2,
          "usleep_retry": 100
       }
    }
}
Keyword Description Version
mysql_error_codes

List of transient error codes. You may add any MySQL error code to the list. It is possible to consider any error as transient not only 1297 (HY000 (ER_GET_TEMPORARY_ERRMSG), Message: Got temporary error %d '%s' from %s). Before adding other codes but 1297 to the list, make sure your cluster supports a new attempt without impacting the state of your application.

Since 1.6.0.
max_retries

How often to retry an operation which fails with a transient error before forwarding the failure to the user.

Default: 1

Since 1.6.0.
usleep_retry

Milliseconds to sleep between transient error retries. The value is passed to the C function usleep, hence the name.

Default: 100

Since 1.6.0.

xa object
The setting has been introduced in 1.6.0.

Note: Experimental

The feature is currently under development. There may be issues and/or feature limitations. Do not use in production environments.

state_store
record_participant_credentials
Whether to store the username and password of a global transaction participant in the participants table. If disabled, the garbage collection will use the default username and password when connecting to the participants. Unless you are using a different username and password for each of your MySQL servers, you can use the default and avoid storing the sensible information in state store.

Please note, username and password are stored in clear text when using the MySQL state store, which is the only one available. It is in your responsibility to protect this sensible information.

Default: false

participant_localhost_ip
During XA garbage collection the plugin may find a participant server for which the host localhost has been recorded. If the garbage collection takes place on another host but the host that has written the participant record to the state store, the host name localhost now resolves to a different host. Therefore, when recording a participant servers host name in the state store, a value of localhost must be replaced with the actual IP address of localhost.

Setting participant_localhost_ip should be considered only if using localhost cannot be avoided. From a garbage collection point of view only, it is preferrable not to configure any socket connection but to provide an IP address and port for a node.

mysql
The MySQL state store is the only state store available.

global_trx_table
Name of the MySQL table used to store the state of an ongoing or aborted global transaction. Use the below SQL statement to create the table. Make sure to edit the table name to match your configuration.

Default: mysqlnd_ms_xa_trx

示例 #33 SQL definition for the MySQL state store transaction table

CREATE TABLE mysqlnd_ms_xa_trx (
  store_trx_id int(11) NOT NULL AUTO_INCREMENT,
  gtrid int(11) NOT NULL,
  format_id int(10) unsigned NOT NULL DEFAULT '1',
  state enum('XA_NON_EXISTING','XA_ACTIVE','XA_IDLE','XA_PREPARED','XA_COMMIT','XA_ROLLBACK') NOT NULL DEFAULT 'XA_NON_EXISTING',
  intend enum('XA_NON_EXISTING','XA_ACTIVE','XA_IDLE','XA_PREPARED','XA_COMMIT','XA_ROLLBACK') DEFAULT 'XA_NON_EXISTING',
  finished enum('NO','SUCCESS','FAILURE') NOT NULL DEFAULT 'NO',
  modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  started datetime DEFAULT NULL,
  timeout datetime DEFAULT NULL,
  PRIMARY KEY (store_trx_id),
  KEY idx_xa_id (gtrid,format_id,finished),
  KEY idx_state (state)
) ENGINE=InnoDB

participant_table
Name of the MySQL table used to store participants of an ongoing or aborted global transaction. Use the below SQL statement to create the table. Make sure to edit the table name to match your configuration.

Storing credentials can be enabled and disabled using record_participant_credentials

Default: mysqlnd_ms_xa_participants

示例 #34 SQL definition for the MySQL state store transaction table

CREATE TABLE mysqlnd_ms_xa_participants (
  fk_store_trx_id int(11) NOT NULL,
  bqual varbinary(64) NOT NULL DEFAULT '',
  participant_id int(10) unsigned NOT NULL AUTO_INCREMENT,
  server_uuid varchar(127) DEFAULT NULL,
  scheme varchar(1024) NOT NULL,
  host varchar(127) DEFAULT NULL,
  port smallint(5) unsigned DEFAULT NULL,
  socket varchar(127) DEFAULT NULL,
  user varchar(127) DEFAULT NULL,
  password varchar(127) DEFAULT NULL,
  state enum('XA_NON_EXISTING','XA_ACTIVE','XA_IDLE','XA_PREPARED','XA_COMMIT','XA_ROLLBACK')
   NOT NULL DEFAULT 'XA_NON_EXISTING',
  health enum('OK','GC_DONE','CLIENT ERROR','SERVER ERROR') NOT NULL DEFAULT 'OK',
  connection_id int(10) unsigned DEFAULT NULL,
  client_errno smallint(5) unsigned DEFAULT NULL,
  client_error varchar(1024) DEFAULT NULL,
  modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (participant_id),
  KEY idx_xa_bqual (bqual),
  KEY idx_store_trx (fk_store_trx_id),
  CONSTRAINT mysqlnd_ms_xa_participants_ibfk_1 FOREIGN KEY (fk_store_trx_id)
    REFERENCES mysqlnd_ms_xa_trx (store_trx_id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB

garbage_collection_table
Name of the MySQL table used to track and synchronize garbage collection runs. Use the below SQL statement to create the table. Make sure to edit the table name to match your configuration.

Default: mysqlnd_ms_xa_gc

示例 #35 SQL definition for the MySQL state store garbage collection table

CREATE TABLE mysqlnd_ms_xa_gc (
  gc_id int(10) unsigned NOT NULL AUTO_INCREMENT,
  gtrid int(11) NOT NULL,
  format_id int(10) unsigned NOT NULL DEFAULT '1',
  fk_store_trx_id int(11) DEFAULT NULL,
  modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  attempts smallint(5) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (gc_id),
  KEY idx_store_trx (gtrid,format_id,fk_store_trx_id)
) ENGINE=InnoDB

host
Host name of the MySQL server.

user
Name of the user used to connect to the MySQL server.

password
Password for the MySQL server user.

db
Database that holds the garbage collection tables. Please note, you have to create the garbage collection tables prior to using the plugin. The tables will not be created implicitly during runtime but garbage collection will fail if the tables to not exist.

port
Port of the MySQL server.

socket
Unix domain socket of the MySQL server. Please note, if you have multiple PHP servers each of them will try to carry out garbage collection and need to be able to connect to the state store. In this case, you may prefer configuring an IP address and a port for the MySQL state store server to ensure all PHP servers can reach it.

rollback_on_close
Whether to automatically rollback an open global transaction when a connection is closed. If enabled, it mimics the default behaviour of local transactions. Should a client disconnect, the server rolls back any open and unfinished transactions.

Default: true

garbage_collection
max_retries
Maximum number of garbage collection runs before giving up. Allowed values are from 0 to 100. A setting of 0 means no limit, unless the state store enforces a limit. Should the state store enforce a limit, it can be supposed to be significantly higher than 100. Available since 1.6.0.

Please note, it is important to end failed XA transactions within reasonable time to make participating servers free resources bound to the transaction. The built-in garbage collection is not expected to fail for a long period as long as crashed servers become available again quickly. Still, a situation may arise where a human is required to act because the built-in garbage collection stopped or failed. In this case, you may first want to check if the transaction still cannot be fixed by forcing mysqlnd_ms_xa_gc to ignore the setting, prior to handling it manually.

Default: 5

probability
Garbage collection probability. Allowed values are from 0 to 1000. A setting of 0 disables automatic background garbage collection. Despite a setting of 0 it is still possible to trigger garbage collection by calling mysqlnd_ms_gc. Available since 1.6.0.

The automatic garbage collection of stalled XA transaction is only available if a state store have been configured. The state store is responsible to keep track of XA transactions. Based on its recordings it can find blocked XA transactions where the client has crashed, connect to the participants and rollback the unfinished transactions.

The garbage collection is triggered as part of PHP's request shutdown procedure at the end of a web request. That is after your PHP script has finished working. Do decide whether to run the garbage collection a random value between 0 and 1000 is computed. If the probability value is higher or equal to the random value, the state stores garbage collection routines are invoked.

Default: 5

max_transactions_per_run
Maximum number of unfinished XA transactions considered by the garbage collection during one run. Allowed values are from 1 to 32768. Available since 1.6.0.

Cleaning up an unfinished XA transaction takes considerable amounts of time and resources. The garbage collection routine may have to connect to several participants of a failed global transaction to issue the SQL commands for rolling back the unfinished tranaction.

Default: 100

Plugin configuration file (\<= 1.0.x)

Note:

The below description applies to PECL/mysqlnd_ms \< 1.1.0-beta. It is not valid for later versions.

The plugin is using its own configuration file. The configuration file holds information on the MySQL replication master server, the MySQL replication slave servers, the server pick (load balancing) policy, the failover strategy and the use of lazy connections.

The PHP configuration directive mysqlnd_ms.ini_file is used to set the plugins configuration file.

The configuration file mimics standard the php.ini format. It consists of one or more sections. Every section defines its own unit of settings. There is no global section for setting defaults.

Applications reference sections by their name. Applications use section names as the host (server) parameter to the various connect methods of the mysqli, mysql and PDO_MYSQL extensions. Upon connect the mysqlnd plugin compares the hostname with all section names from the plugin configuration file. If hostname and section name match, the plugin will load the sections settings.

示例 #36 Using section names example

[myapp]
master[] = localhost
slave[] = 192.168.2.27
slave[] = 192.168.2.28:3306
[localhost]
master[] = localhost:/tmp/mysql/mysql.sock
slave[] = 192.168.3.24:3305
slave[] = 192.168.3.65:3309
<?php
/* All of the following connections will be load balanced */
$mysqli = new mysqli("myapp", "username", "password", "database");
$pdo = new PDO('mysql:host=myapp;dbname=database', 'username', 'password');
$mysql = mysql_connect("myapp", "username", "password");

$mysqli = new mysqli("localhost", "username", "password", "database");
?>

Section names are strings. It is valid to use a section name such as 192.168.2.1, 127.0.0.1 or localhost. If, for example, an application connects to localhost and a plugin configuration section [localhost] exists, the semantics of the connect operation are changed. The application will no longer only use the MySQL server running on the host localhost but the plugin will start to load balance MySQL queries following the rules from the [localhost] configuration section. This way you can load balance queries from an application without changing the applications source code.

The master[], slave[] and pick[] configuration directives use a list-like syntax. Configuration directives supporting list-like syntax may appear multiple times in a configuration section. The plugin maintains the order in which entries appear when interpreting them. For example, the below example shows two slave[] configuration directives in the configuration section [myapp]. If doing round-robin load balancing for read-only queries, the plugin will send the first read-only query to the MySQL server mysql_slave_1 because it is the first in the list. The second read-only query will be send to the MySQL server mysql_slave_2 because it is the second in the list. Configuration directives supporting list-like syntax result are ordered from top to bottom in accordance to their appearance within a configuration section.

示例 #37 List-like syntax

[myapp]
master[] = mysql_master_server
slave[] = mysql_slave_1
slave[] = mysql_slave_2

Here is a short explanation of the configuration directives that can be used.

master[] string
URI of a MySQL replication master server. The URI follows the syntax hostname[:port|unix_domain_socket].

The plugin supports using only one master server.

Setting a master server is mandatory. The plugin will report a warning upon connect if the user has failed to provide a master server for a configuration section. The warning may read (mysqlnd_ms) Cannot find master section in config. Furthermore the plugin may set an error code for the connection handle such as HY000/2000 (CR_UNKNOWN_ERROR). The corresponding error message depends on your language settings.

slave[] string
URI of one or more MySQL replication slave servers. The URI follows the syntax hostname[:port|unix_domain_socket].

The plugin supports using one or more slave servers.

Setting a slave server is mandatory. The plugin will report a warning upon connect if the user has failed to provide at least one slave server for a configuration section. The warning may read (mysqlnd_ms) Cannot find slaves section in config. Furthermore the plugin may set an error code for the connection handle such as HY000/2000 (CR_UNKNOWN_ERROR). The corresponding error message depends on your language settings.

pick[] string
Load balancing (server picking) policy. Supported policies: random, random_once (default), roundrobin, user.

If no load balancing policy is set, the plugin will default to random_once. The random_once policy picks a random slave server when running the first read-only statement. The slave server will be used for all read-only statements until the PHP script execution ends.

The random policy will pick a random server whenever a read-only statement is to be executed.

If using roundrobin the plugin iterates over the list of configured slave servers to pick a server for statement execution. If the plugin reaches the end of the list, it wraps around to the beginning of the list and picks the first configured slave server.

Setting more than one load balancing policy for a configuration section makes only sense in conjunction with user and <span class="function">mysqlnd_ms_set_user_pick_server. If the user defined callback fails to pick a server, the plugin falls back to the second configured load balancing policy.

failover string
Failover policy. Supported policies: disabled (default), master.

If no failover policy is set, the plugin will not do any automatic failover (failover=disabled). Whenever the plugin fails to connect a server it will emit a warning and set the connections error code and message. Thereafter it is up to the application to handle the error and, for example, resent the last statement to trigger the selection of another server.

If using failover=master the plugin will implicitly failover to a slave, if available. Please check the concepts documentation to learn about potential pitfalls and risks of using failover=master.

lazy_connections bool
Controls the use of lazy connections. Lazy connections are connections which are not opened before the client sends the first connection.

It is strongly recommended to use lazy connections. Lazy connections help to keep the number of open connections low. If you disable lazy connections and, for example, configure one MySQL replication master server and two MySQL replication slaves, the plugin will open three connections upon the first call to a connect function although the application might use the master connection only.

Lazy connections bare a risk if you make heavy use of actions which change the state of a connection. The plugin does not dispatch all state changing actions to all connections from the connection pool. The few dispatched actions are applied to already opened connections only. Lazy connections opened in the future are not affected. If, for example, the connection character set is changed using a PHP MySQL API call, the plugin will change the character set of all currently opened connection. It will not remember the character set change to apply it on lazy connections opened in the future. As a result the internal connection pool would hold connections using different character sets. This is not desired. Remember that character sets are taken into account for escaping.

master_on_write bool
If set, the plugin will use the master server only after the first statement has been executed on the master. Applications can still send statements to the slaves using SQL hints to overrule the automatic decision.

The setting may help with replication lag. If an application runs an INSERT the plugin will, by default, use the master to execute all following statements, including SELECT statements. This helps to avoid problems with reads from slaves which have not replicated the INSERT yet.

trx_stickiness string
Transaction stickiness policy. Supported policies: disabled (default), master.

Experimental feature.

The setting requires 5.4.0 or newer. If used with PHP older than 5.4.0, the plugin will emit a warning like (mysqlnd_ms) trx_stickiness strategy is not supported before PHP 5.3.99.

If no transaction stickiness policy is set or, if setting trx_stickiness=disabled, the plugin is not transaction aware. Thus, the plugin may load balance connections and switch connections in the middle of a transaction. The plugin is not transaction safe. SQL hints must be used avoid connection switches during a transaction.

As of PHP 5.4.0 the mysqlnd library allows the plugin to monitor the autocommit mode set by calls to the libraries trx_autocommit() function. If setting trx_stickiness=master and autocommit gets disabled by a PHP MySQL extension invoking the mysqlnd library internal function call trx_autocommit(), the plugin is made aware of the begin of a transaction. Then, the plugin stops load balancing and directs all statements to the master server until autocommit is enabled. Thus, no SQL hints are required.

An example of a PHP MySQL API function calling the mysqlnd library internal function call trx_autocommit() is <span class="function">mysqli_autocommit.

Although setting trx_stickiness=master, the plugin cannot be made aware of autocommit mode changes caused by SQL statements such as SET AUTOCOMMIT=0.

Testing

Note:

The section applies to mysqlnd_ms 1.1.0 or newer, not the 1.0 series.

The PECL/mysqlnd_ms test suite is in the tests/ directory of the source distribution. The test suite consists of standard phpt tests, which are described on the PHP Quality Assurance Teams website.

Running the tests requires setting up one to four MySQL servers. Some tests don't connect to MySQL at all. Others require one server for testing. Some require two distinct servers. In some cases two servers are used to emulate a replication setup. In other cases a master and a slave of an existing MySQL replication setup are required for testing. The tests will try to detect how many servers and what kind of servers are given. If the required servers are not found, the test will be skipped automatically.

Before running the tests, edit tests/config.inc to configure the MySQL servers to be used for testing.

The most basic configuration is as follows.

 putenv("MYSQL_TEST_HOST=localhost");
 putenv("MYSQL_TEST_PORT=3306");
 putenv("MYSQL_TEST_USER=root");
 putenv("MYSQL_TEST_PASSWD=");
 putenv("MYSQL_TEST_DB=test");
 putenv("MYSQL_TEST_ENGINE=MyISAM");
 putenv("MYSQL_TEST_SOCKET=");

 putenv("MYSQL_TEST_SKIP_CONNECT_FAILURE=1");
 putenv("MYSQL_TEST_CONNECT_FLAGS=0");
 putenv("MYSQL_TEST_EXPERIMENTAL=0");

 /* replication cluster emulation */
 putenv("MYSQL_TEST_EMULATED_MASTER_HOST=". getenv("MYSQL_TEST_HOST"));
 putenv("MYSQL_TEST_EMULATED_SLAVE_HOST=". getenv("MYSQL_TEST_HOST"));

 /* real replication cluster */
 putenv("MYSQL_TEST_MASTER_HOST=". getenv("MYSQL_TEST_EMULATED_MASTER_HOST"));
 putenv("MYSQL_TEST_SLAVE_HOST=". getenv("MYSQL_TEST_EMULATED_SLAVE_HOST"));

MYSQL_TEST_HOST, MYSQL_TEST_PORT and MYSQL_TEST_SOCKET define the hostname, TCP/IP port and Unix domain socket of the default database server. MYSQL_TEST_USER and MYSQL_TEST_PASSWD contain the user and password needed to connect to the database/schema configured with MYSQL_TEST_DB. All configured servers must have the same database user configured to give access to the test database.

Using host, host:port or host:/path/to/socket syntax one can set an alternate host, host and port or host and socket for any of the servers.

putenv("MYSQL_TEST_SLAVE_HOST=192.168.78.136:3307"));
putenv("MYSQL_TEST_MASTER_HOST=myserver_hostname:/path/to/socket"));

Debugging and Tracing

The mysqlnd debug log can be used to debug and trace the actitivities of PECL/mysqlnd_ms. As a mysqlnd PECL/mysqlnd_ms adds trace information to the mysqlnd library debug file. Please, see the mysqlnd.debug PHP configuration directive documentation for a detailed description on how to configure the debug log.

Configuration setting example to activate the debug log:

mysqlnd.debug=d:t:x:O,/tmp/mysqlnd.trace

Note:

This feature is only available with a debug build of PHP. Works on Microsoft Windows if using a debug build of PHP and PHP was built using Microsoft Visual C version 9 and above.

The debug log shows mysqlnd library and PECL/mysqlnd_ms plugin function calls, similar to a trace log. Mysqlnd library calls are usually prefixed with mysqlnd_. PECL/mysqlnd internal calls begin with mysqlnd_ms.

Example excerpt from the debug log (connect):

[...]
>mysqlnd_connect
| info : host=myapp user=root db=test port=3306 flags=131072
| >mysqlnd_ms::connect
| | >mysqlnd_ms_config_json_section_exists
| | | info : section=[myapp] len=[5]
| | | >mysqlnd_ms_config_json_sub_section_exists
| | | | info : section=[myapp] len=[5]
| | | | info : ret=1
| | | <mysqlnd_ms_config_json_sub_section_exists
| | | info : ret=1
| | <mysqlnd_ms_config_json_section_exists
[...]

The debug log is not only useful for plugin developers but also to find the cause of user errors. For example, if your application does not do proper error handling and fails to record error messages, checking the debug and trace log may help finding the cause. Use of the debug log to debug application issues should be considered only if no other option is available. Writing the debug log to disk is a slow operation and may have negative impact on the application performance.

Example excerpt from the debug log (connection failure):

[...]
| | | | | | | info : adding error [Access denied for user 'root'@'localhost' (using password: YES)] to the list
| | | | | | | info : PACKET_FREE(0)
| | | | | | | info : PACKET_FREE(0x7f3ef6323f50)
| | | | | | | info : PACKET_FREE(0x7f3ef6324080)
| | | | | | <mysqlnd_auth_handshake
| | | | | | info : switch_to_auth_protocol=n/a
| | | | | | info : conn->error_info.error_no = 1045
| | | | | <mysqlnd_connect_run_authentication
| | | | | info : PACKET_FREE(0x7f3ef63236d8)
| | | | | >mysqlnd_conn::free_contents
| | | | | | >mysqlnd_net::free_contents
| | | | | | <mysqlnd_net::free_contents
| | | | | | info : Freeing memory of members
| | | | | | info : scheme=unix:///tmp/mysql.sock
| | | | | | >mysqlnd_error_list_pdtor
| | | | | | <mysqlnd_error_list_pdtor
| | | | | <mysqlnd_conn::free_contents
| | | | <mysqlnd_conn::connect
[...]

The trace log can also be used to verify correct behaviour of PECL/mysqlnd_ms itself, for example, to check which server has been selected for query execution and why.

Example excerpt from the debug log (plugin decision):

[...]
>mysqlnd_ms::query
| info : query=DROP TABLE IF EXISTS test
| >_mysqlnd_plugin_get_plugin_connection_data
| | info : plugin_id=5
| <_mysqlnd_plugin_get_plugin_connection_data
| >mysqlnd_ms_pick_server_ex
| | info : conn_data=0x7fb6a7d3e5a0 *conn_data=0x7fb6a7d410d0
| | >mysqlnd_ms_select_servers_all
| | <mysqlnd_ms_select_servers_all
| | >mysqlnd_ms_choose_connection_rr
| | | >mysqlnd_ms_query_is_select
[...]
| | | <mysqlnd_ms_query_is_select
[...]
| | | info : Init the master context
| | | info : list(0x7fb6a7d3f598) has 1
| | | info : Using master connection
| | | >mysqlnd_ms_advanced_connect
| | | | >mysqlnd_conn::connect
| | | | | info : host=localhost user=root db=test port=3306 flags=131072 persistent=0 state=0

In this case the statement DROP TABLE IF EXISTS test has been executed. Note that the statement string is shown in the log file. You may want to take measures to restrict access to the log for security considerations.

The statement has been load balanced using round robin policy, as you can easily guess from the functions name >mysqlnd_ms_choose_connection_rr. It has been sent to a master server running on host=localhost user=root db=test port=3306 flags=131072 persistent=0 state=0.

Monitoring

Plugin activity can be monitored using the mysqlnd trace log, mysqlnd statistics, mysqlnd_ms plugin statistics and external PHP debugging tools. Use of the trace log should be limited to debugging. It is recommended to use the plugins statistics for monitoring.

Writing a trace log is a slow operation. If using an external PHP debugging tool, please refer to the vendors manual about its performance impact and the type of information collected. In many cases, external debugging tools will provide call stacks. Often, a call stack or a trace log is more difficult to interpret than the statistics provided by the plugin.

Plugin statistics tell how often which kind of cluster node has been used (slave or master), why the node was used, if lazy connections have been used and if global transaction ID injection has been performed. The monitoring information provided enables user to verify plugin decisions and to plan their cluster resources based on usage pattern. The function mysqlnd_ms_get_stats is used to access the statistics. Please, see the functions description for a list of available statistics.

Statistics are collected on a per PHP process basis. Their scope is a PHP process. Depending on the PHP deployment model a process may serve one or multiple web requests. If using CGI model, a PHP process serves one web request. If using FastCGI or pre-fork web server models, a PHP process usually serves multiple web requests. The same is the case with a threaded web server. Please, note that threads running in parallel can update the statistics in parallel. Thus, if using a threaded PHP deployment model, statistics can be changed by more than one script at a time. A script cannot rely on the fact that it sees only its own changes to statistics.

示例 #38 Verify plugin activity in a non-threaded deployment model

mysqlnd_ms.enable=1
mysqlnd_ms.collect_statistics=1
<?php
/* Load balanced following "myapp" section rules from the plugins config file (not shown) */
$mysqli = new mysqli("myapp", "username", "password", "database");
if (mysqli_connect_errno())
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

$stats_before = mysqlnd_ms_get_stats();
if ($res = $mysqli->query("SELECT 'Read request' FROM DUAL")) {
  var_dump($res->fetch_all());
}
$stats_after = mysqlnd_ms_get_stats();
if ($stats_after['use_slave'] <= $stats_before['use_slave']) {
  echo "According to the statistics the read request has not been run on a slave!";
}
?>

Statistics are aggregated for all plugin activities and all connections handled by the plugin. It is not possible to tell how much a certain connection handle has contributed to the overall statistics.

Utilizing PHPs <span class="function">register_shutdown_function function or the auto_append_file PHP configuration directive it is easily possible to dump statistics into, for example, a log file when a script finishes. Instead of using a log file it is also possible to send the statistics to an external monitoring tool for recording and display.

示例 #39 Recording statistics during shutdown

mysqlnd_ms.enable=1
mysqlnd_ms.collect_statistics=1
error_log=/tmp/php_errors.log
<?php
function check_stats() {
  $msg = str_repeat("-", 80) . "\n";
  $msg .= var_export(mysqlnd_ms_get_stats(), true) . "\n";
  $msg .= str_repeat("-", 80) . "\n";
  error_log($msg);
}
register_shutdown_function("check_stats");
?>

预定义常量

下列常量由此扩展定义,且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

SQL hint related

示例 #1 Example demonstrating the usage of mysqlnd_ms constants

The mysqlnd replication and load balancing plugin (mysqlnd_ms) performs read/write splitting. This directs write queries to a MySQL master server, and read-only queries to the MySQL slave servers. The plugin has a built-in read/write split logic. All queries which start with SELECT are considered read-only queries, which are then sent to a MySQL slave server that is listed in the plugin configuration file. All other queries are directed to the MySQL master server that is also specified in the plugin configuration file.

User supplied SQL hints can be used to overrule automatic read/write splitting, to gain full control on the process. SQL hints are standards compliant SQL comments. The plugin will scan the beginning of a query string for an SQL comment for certain commands, which then control query redirection. Other systems involved in the query processing are unaffected by the SQL hints because other systems will ignore the SQL comments.

The plugin supports three SQL hints to direct queries to either the MySQL slave servers, the MySQL master server, or the last used MySQL server. SQL hints must be placed at the beginning of a query to be recognized by the plugin.

For better portability, it is recommended to use the string constants MYSQLND_MS_MASTER_SWITCH, MYSQLND_MS_SLAVE_SWITCH and MYSQLND_MS_LAST_USED_SWITCH instead of their literal values.

<?php
/* Use constants for maximum portability */
$master_query = "/*" . MYSQLND_MS_MASTER_SWITCH . "*/SELECT id FROM test";

/* Valid but less portable: using literal instead of constant */
$slave_query = "/*ms=slave*/SHOW TABLES";

printf("master_query = '%s'\n", $master_query);
printf("slave_query = '%s'\n", $slave_query);
?>

以上例程会输出:

master_query = /*ms=master*/SELECT id FROM test
slave_query = /*ms=slave*/SHOW TABLES

MYSQLND_MS_MASTER_SWITCH (string)
SQL hint used to send a query to the MySQL replication master server.

MYSQLND_MS_SLAVE_SWITCH (string)
SQL hint used to send a query to one of the MySQL replication slave servers.

MYSQLND_MS_LAST_USED_SWITCH (string)
SQL hint used to send a query to the last used MySQL server. The last used MySQL server can either be a master or a slave server in a MySQL replication setup.

mysqlnd_ms_query_is_select related

MYSQLND_MS_QUERY_USE_MASTER (int)
If <span class="function">mysqlnd_ms_is_select returns MYSQLND_MS_QUERY_USE_MASTER for a given query, the built-in read/write split mechanism recommends sending the query to a MySQL replication master server.

MYSQLND_MS_QUERY_USE_SLAVE (int)
If <span class="function">mysqlnd_ms_is_select returns MYSQLND_MS_QUERY_USE_SLAVE for a given query, the built-in read/write split mechanism recommends sending the query to a MySQL replication slave server.

MYSQLND_MS_QUERY_USE_LAST_USED (int)
If <span class="function">mysqlnd_ms_is_select returns MYSQLND_MS_QUERY_USE_LAST_USED for a given query, the built-in read/write split mechanism recommends sending the query to the last used server.

mysqlnd_ms_set_qos, quality of service filter and service level related

MYSQLND_MS_QOS_CONSISTENCY_EVENTUAL (int)
Use to request the service level eventual consistency from the <span class="function">mysqlnd_ms_set_qos. Eventual consistency is the default quality of service when reading from an asynchronous MySQL replication slave. Data returned in this service level may or may not be stale, depending on whether the selected slaves happen to have replicated the latest changes from the MySQL replication master or not.

MYSQLND_MS_QOS_CONSISTENCY_SESSION (int)
Use to request the service level session consistency from the <span class="function">mysqlnd_ms_set_qos. Session consistency is defined as read your writes. The client is guaranteed to see his latest changes.

MYSQLND_MS_QOS_CONSISTENCY_STRONG (int)
Use to request the service level strong consistency from the <span class="function">mysqlnd_ms_set_qos. Strong consistency is used to ensure all clients see each others changes.

MYSQLND_MS_QOS_OPTION_GTID (int)
Used as a service level option with <span class="function">mysqlnd_ms_set_qos to parameterize session consistency.

MYSQLND_MS_QOS_OPTION_AGE (int)
Used as a service level option with <span class="function">mysqlnd_ms_set_qos to parameterize eventual consistency.

Other

The plugins version number can be obtained using MYSQLND_MS_VERSION or MYSQLND_MS_VERSION_ID. MYSQLND_MS_VERSION is the string representation of the numerical version number MYSQLND_MS_VERSION_ID, which is an integer such as 10000. Developers can calculate the version number as follows.

Version (part) Example
Major*10000 1*10000 = 10000
Minor*100 0*100 = 0
Patch 0 = 0
MYSQLND_MS_VERSION_ID 10000

MYSQLND_MS_VERSION (string)
Plugin version string, for example, “1.0.0-prototype”.

MYSQLND_MS_VERSION_ID (int)
Plugin version number, for example, 10000.

mysqlnd_ms_dump_servers

Returns a list of currently configured servers

说明

array <span class="methodname">mysqlnd_ms_dump_servers ( <span class="methodparam">mixed $connection )

Returns a list of currently configured servers.

参数

connection
A MySQL connection handle obtained from any of the connect functions of the mysqli, mysql or PDO_MYSQL extensions.

返回值

false on error. Otherwise, returns an array with two entries masters and slaves each of which contains an array listing all corresponding servers.

The function can be used to check and debug the list of servers currently used by the plugin. It is mostly useful when the list of servers changes at runtime, for example, when using MySQL Fabric.

masters and slaves server entries

Key Description Version
name_from_config Server entry name from config, if appliciable. NULL if no configuration name is available. Since 1.6.0.
hostname Host name of the server. Since 1.6.0.
user Database user used to authenticate against the server. Since 1.6.0.
port TCP/IP port of the server. Since 1.6.0.
socket Unix domain socket of the server. Since 1.6.0.

注释

Note:

mysqlnd_ms_dump_servers requires PECL mysqlnd_ms >> 1.6.0.

范例

示例 #1 mysqlnd_ms_dump_servers example

{
    "myapp": {
        "master": {
            "master1": {
                "host":"master1_host",
                "port":"master1_port",
                "socket":"master1_socket",
                "db":"master1_db",
                "user":"master1_user",
                "password":"master1_pw"
            }
        },
        "slave": {
             "slave_0": {
                 "host":"slave0_host",
                 "port":"slave0_port",
                 "socket":"slave0_socket",
                 "db":"slave0_db",
                 "user":"slave0_user",
                 "password":"slave0_pw"
             },
             "slave_1": {
                 "host":"slave1_host"
             }
        }
    }
}
<?php
$link = mysqli_connect("myapp", "global_user", "global_pass", "global_db", 1234, "global_socket");
var_dump(mysqlnd_ms_dump_servers($link);
?>

以上例程会输出:

array(2) {
  ["masters"]=>
  array(1) {
    [0]=>
    array(5) {
      ["name_from_config"]=>
      string(7) "master1"
      ["hostname"]=>
      string(12) "master1_host"
      ["user"]=>
      string(12) "master1_user"
      ["port"]=>
      int(3306)
      ["socket"]=>
      string(14) "master1_socket"
    }
  }
  ["slaves"]=>
  array(2) {
    [0]=>
    array(5) {
      ["name_from_config"]=>
      string(7) "slave_0"
      ["hostname"]=>
      string(11) "slave0_host"
      ["user"]=>
      string(11) "slave0_user"
      ["port"]=>
      int(3306)
      ["socket"]=>
      string(13) "slave0_socket"
    }
    [1]=>
    array(5) {
      ["name_from_config"]=>
      string(7) "slave_1"
      ["hostname"]=>
      string(11) "slave1_host"
      ["user"]=>
      string(12) "gloabal_user"
      ["port"]=>
      int(1234)
      ["socket"]=>
      string(13) "global_socket"
    }
  }
}

mysqlnd_ms_fabric_select_global

Switch to global sharding server for a given table

说明

array <span class="methodname">mysqlnd_ms_fabric_select_global ( <span class="methodparam">mixed $connection , mixed $table_name )

Warning

本函数还未编写文档,仅有参数列表。

MySQL Fabric related.

Switch the connection to the nodes handling global sharding queries for the given table name.

参数

connection
A MySQL connection handle obtained from any of the connect functions of the mysqli, mysql or PDO_MYSQL extensions.

table_name
The table name to ask Fabric about.

返回值

false on error. Otherwise, true

注释

Note:

mysqlnd_ms_fabric_select_global requires PECL mysqlnd_ms >> 1.6.0.

mysqlnd_ms_fabric_select_shard

Switch to shard

说明

array <span class="methodname">mysqlnd_ms_fabric_select_shard ( <span class="methodparam">mixed $connection , mixed $table_name , <span class="type">mixed $shard_key )

Warning

本函数还未编写文档,仅有参数列表。

MySQL Fabric related.

Switch the connection to the shards responsible for the given table name and shard key.

参数

connection
A MySQL connection handle obtained from any of the connect functions of the mysqli, mysql or PDO_MYSQL extensions.

table_name
The table name to ask Fabric about.

shard_key
The shard key to ask Fabric about.

返回值

false on error. Otherwise, true

注释

Note:

mysqlnd_ms_fabric_select_shard requires PECL mysqlnd_ms >> 1.6.0.

mysqlnd_ms_get_last_gtid

返回最后的全局同步 ID (GTID)

说明

string <span class="methodname">mysqlnd_ms_get_last_gtid ( <span class="methodparam">mixed $connection )

返回最后一次写操作以后的 GTID,他并不能保证一定是那次写操作产生的 GTID,但是得到的 GTID 一定比这次写操作产生的 GTID 大。

参数

connection
PDO_MYSQL, mysqli> 或者 ext/mysql 产生的 MySQL 服务器连接, 这些链接受 PECL/mysqlnd_ms 连接控制。连接的创建是通过 mysqlnd_ms 配置文件中 约定的群组名称建立的。

返回值

成功返回 GTID,失败返回 false

函数通过配置文件中 global_transaction_id_injection 章节定义的 fetch_last_gtid 参数来获取 GTID。

在函数调用的时候,GTID 可能已经增加了。

注释

Note:

函数需要 PHP >= 5.4.0 版本,PECL/mysqlnd_ms >= 1.2.0 版本,在 PHP 5.3 版本中 mysqlnd 库不能使用。

范例

示例 #1 mysqlnd_ms_get_last_gtid example

<?php
/* Open mysqlnd_ms connection using mysqli, PDO_MySQL or mysql extension */
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* auto commit mode, transaction on master, GTID must be incremented */
if (!$mysqli->query("DROP TABLE IF EXISTS test"))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

printf("GTID after transaction %s\n", mysqlnd_ms_get_last_gtid($mysqli));

/* auto commit mode, transaction on master, GTID must be incremented */
if (!$mysqli->query("CREATE TABLE test(id INT)"))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

printf("GTID after transaction %s\n", mysqlnd_ms_get_last_gtid($mysqli));
?>

参见

mysqlnd_ms_get_last_used_connection

Returns an array which describes the last used connection

说明

array <span class="methodname">mysqlnd_ms_get_last_used_connection ( mixed $connection )

Returns an array which describes the last used connection from the plugins connection pool currently pointed to by the user connection handle. If using the plugin, a user connection handle represents a pool of database connections. It is not possible to tell from the user connection handles properties to which database server from the pool the user connection handle points.

The function can be used to debug or monitor PECL mysqlnd_ms.

参数

connection
A MySQL connection handle obtained from any of the connect functions of the mysqli, mysql or PDO_MYSQL extensions.

返回值

false on error. Otherwise, an array which describes the connection used to execute the last statement on.

Array which describes the connection.

Property Description Version
scheme Connection scheme. Either tcp://host:port or unix://host:socket. If you want to distinguish connections from each other use a combination of scheme and thread_id as a unique key. Neither scheme nor thread_id alone are sufficient to distinguish two connections from each other. Two servers may assign the same thread_id to two different connections. Thus, connections in the pool may have the same thread_id. Also, do not rely on uniqueness of scheme in a pool. Your QA engineers may use the same MySQL server instance for two distinct logical roles and add it multiple times to the pool. This hack is used, for example, in the test suite. Since 1.1.0.
host Database server host used with the connection. The host is only set with TCP/IP connections. It is empty with Unix domain or Windows named pipe connections, Since 1.1.0.
host_info A character string representing the server hostname and the connection type. Since 1.1.2.
port Database server port used with the connection. Since 1.1.0.
socket_or_pipe Unix domain socket or Windows named pipe used with the connection. The value is empty for TCP/IP connections. Since 1.1.2.
thread_id Connection thread id. Since 1.1.0.
last_message Info message obtained from the MySQL C API function mysql_info(). Please, see mysqli_info for a description. Since 1.1.0.
errno Error code. Since 1.1.0.
error Error message. Since 1.1.0.
sqlstate Error SQLstate code. Since 1.1.0.

注释

Note:

mysqlnd_ms_get_last_used_connection requires PHP >= 5.4.0 and PECL mysqlnd_ms >> 1.1.0. Internally, it is using a mysqlnd library C call not available with PHP 5.3.

范例

The example assumes that myapp refers to a plugin configuration file section and represents a connection pool.

示例 #1 <span class="function">mysqlnd_ms_get_last_used_connection example

<?php
$link = new mysqli("myapp", "user", "password", "database");
$res = $link->query("SELECT 1 FROM DUAL");
var_dump(mysqlnd_ms_get_last_used_connection($link));
?>

以上例程会输出:

array(10) {
  ["scheme"]=>
  string(22) "unix:///tmp/mysql.sock"
  ["host_info"]=>
  string(25) "Localhost via UNIX socket"
  ["host"]=>
  string(0) ""
  ["port"]=>
  int(3306)
  ["socket_or_pipe"]=>
  string(15) "/tmp/mysql.sock"
  ["thread_id"]=>
  int(46253)
  ["last_message"]=>
  string(0) ""
  ["errno"]=>
  int(0)
  ["error"]=>
  string(0) ""
  ["sqlstate"]=>
  string(5) "00000"
}

mysqlnd_ms_get_stats

Returns query distribution and connection statistics

说明

array <span class="methodname">mysqlnd_ms_get_stats ( <span class="methodparam">void )

Returns an array of statistics collected by the replication and load balancing plugin.

The PHP configuration setting mysqlnd_ms.collect_statistics controls the collection of statistics. The collection of statistics is disabled by default for performance reasons.

The scope of the statistics is the PHP process. Depending on your deployment model a PHP process may handle one or multiple requests.

Statistics are aggregated for all connections and all storage handler. It is not possible to tell how much queries originating from mysqli, PDO_MySQL or mysql API calls have contributed to the aggregated data values.

参数

此函数没有参数。

返回值

Returns null if the PHP configuration directive mysqlnd_ms.enable has disabled the plugin. Otherwise, returns array of statistics.

Array of statistics

Statistic Description Version
use_slave

The semantics of this statistic has changed between 1.0.1 - 1.1.0.

The meaning for version 1.0.1 is as follows. Number of statements considered as read-only by the built-in query analyzer. Neither statements which begin with a SQL hint to force use of slave nor statements directed to a slave by an user-defined callback are included. The total number of statements sent to the slaves is use_slave + use_slave_sql_hint + use_slave_callback.

PECL/mysqlnd_ms 1.1.0 introduces a new concept of chained filters. The statistics is now set by the internal load balancing filter. With version 1.1.0 the load balancing filter is always the last in the filter chain, if used. In future versions a load balancing filter may be followed by other filters causing another change in the meaning of the statistic. If, in the future, a load balancing filter is followed by another filter it is no longer guaranteed that the statement, which increments use_slave, will be executed on the slaves.

The meaning for version 1.1.0 is as follows. Number of statements sent to the slaves. Statements directed to a slave by the user filter (an user-defined callback) are not included. The latter are counted by use_slave_callback.

Since 1.0.0.
use_master

The semantics of this statistic has changed between 1.0.1 - 1.1.0.

The meaning for version 1.0.1 is as follows. Number of statements not considered as read-only by the built-in query analyzer. Neither statements which begin with a SQL hint to force use of master nor statements directed to a master by an user-defined callback are included. The total number of statements sent to the master is use_master + use_master_sql_hint + use_master_callback.

PECL/mysqlnd_ms 1.1.0 introduces a new concept of chained filters. The statictics is now set by the internal load balancing filter. With version 1.1.0 the load balancing filter is always the last in the filter chain, if used. In future versions a load balancing filter may be followed by other filters causing another change in the meaning of the statistic. If, in the future, a load balancing filter is followed by another filter it is no longer guaranteed that the statement, which increments use_master, will be executed on the slaves.

The meaning for version 1.1.0 is as follows. Number of statements sent to the masters. Statements directed to a master by the user filter (an user-defined callback) are not included. The latter are counted by use_master_callback.

Since 1.0.0.
use_slave_guess Number of statements the built-in query analyzer recommends sending to a slave because they contain no SQL hint to force use of a certain server. The recommendation may be overruled in the following. It is not guaranteed whether the statement will be executed on a slave or not. This is how often the internal is_select function has guessed that a slave shall be used. Please, see also the user space function mysqlnd_ms_query_is_select. Since 1.1.0.
use_master_guess Number of statements the built-in query analyzer recommends sending to a master because they contain no SQL hint to force use of a certain server. The recommendation may be overruled in the following. It is not guaranteed whether the statement will be executed on a slave or not. This is how often the internal is_select function has guessed that a master shall be used. Please, see also the user space function mysqlnd_ms_query_is_select. Since 1.1.0.
use_slave_sql_hint Number of statements sent to a slave because statement begins with the SQL hint to force use of slave. Since 1.0.0.
use_master_sql_hint Number of statements sent to a master because statement begins with the SQL hint to force use of master. Since 1.0.0.
use_last_used_sql_hint Number of statements sent to server which has run the previous statement, because statement begins with the SQL hint to force use of previously used server. Since 1.0.0.
use_slave_callback Number of statements sent to a slave because an user-defined callback has chosen a slave server for statement execution. Since 1.0.0.
use_master_callback Number of statements sent to a master because an user-defined callback has chosen a master server for statement execution. Since 1.0.0.
non_lazy_connections_slave_success Number of successfully opened slave connections from configurations not using lazy connections. The total number of successfully opened slave connections is non_lazy_connections_slave_success + lazy_connections_slave_success Since 1.0.0.
non_lazy_connections_slave_failure Number of failed slave connection attempts from configurations not using lazy connections. The total number of failed slave connection attempts is non_lazy_connections_slave_failure + lazy_connections_slave_failure Since 1.0.0.
non_lazy_connections_master_success Number of successfully opened master connections from configurations not using lazy connections. The total number of successfully opened master connections is non_lazy_connections_master_success + lazy_connections_master_success Since 1.0.0.
non_lazy_connections_master_failure Number of failed master connection attempts from configurations not using lazy connections. The total number of failed master connection attempts is non_lazy_connections_master_failure + lazy_connections_master_failure Since 1.0.0.
lazy_connections_slave_success Number of successfully opened slave connections from configurations using lazy connections. Since 1.0.0.
lazy_connections_slave_failure Number of failed slave connection attempts from configurations using lazy connections. Since 1.0.0.
lazy_connections_master_success Number of successfully opened master connections from configurations using lazy connections. Since 1.0.0.
lazy_connections_master_failure Number of failed master connection attempts from configurations using lazy connections. Since 1.0.0.
trx_autocommit_on Number of autocommit mode activations via API calls. This figure may be used to monitor activity related to the plugin configuration setting trx_stickiness. If, for example, you want to know if a certain API call invokes the mysqlnd library function trx_autocommit(), which is a requirement for trx_stickiness, you may call the user API function in question and check if the statistic has changed. The statistic is modified only by the plugins internal subclassed trx_autocommit() method. Since 1.0.0.
trx_autocommit_off Number of autocommit mode deactivations via API calls. Since 1.0.0.
trx_master_forced Number of statements redirected to the master while trx_stickiness=master and autocommit mode is disabled. Since 1.0.0.
gtid_autocommit_injections_success Number of successful SQL injections in autocommit mode as part of the plugins client-side global transaction id emulation. Since 1.2.0.
gtid_autocommit_injections_failure Number of failed SQL injections in autocommit mode as part of the plugins client-side global transaction id emulation. Since 1.2.0.
gtid_commit_injections_success Number of successful SQL injections in commit mode as part of the plugins client-side global transaction id emulation. Since 1.2.0.
gtid_commit_injections_failure Number of failed SQL injections in commit mode as part of the plugins client-side global transaction id emulation. Since 1.2.0.
gtid_implicit_commit_injections_success Number of successful SQL injections when implicit commit is detected as part of the plugins client-side global transaction id emulation. Implicit commit happens, for example, when autocommit has been turned off, a query is executed and autocommit is enabled again. In that case, the statement will be committed by the server and SQL to maintain is injected before the autocommit is re-enabled. Another sequence causing an implicit commit is begin(), query(), begin(). The second call to begin() will implicitly commit the transaction started by the first call to begin(). begin() refers to internal library calls not actual PHP user API calls. Since 1.2.0.
gtid_implicit_commit_injections_failure Number of failed SQL injections when implicit commit is detected as part of the plugins client-side global transaction id emulation. Implicit commit happens, for example, when autocommit has been turned off, a query is executed and autocommit is enabled again. In that case, the statement will be committed by the server and SQL to maintain is injected before the autocommit is re-enabled. Since 1.2.0.
transient_error_retries How often an operation has been retried when a transient error was detected. See also, transient_error plugin configuration file setting. Since 1.6.0.
fabric_sharding_lookup_servers_success Number of successful sharding.lookup_servers remote procedure calls to MySQL Fabric. A call is considered successful if the plugin could reach MySQL Fabric and got any reply. The reply itself may or may not be understood by the plugin. Success refers to the network transport only. If the reply was not understood or indicates a valid error condition, fabric_sharding_lookup_servers_xml_failure gets incremented. Since 1.6.0.
fabric_sharding_lookup_servers_failure Number of failed sharding.lookup_servers remote procedure calls to MySQL Fabric. A remote procedure call is considered failed if there was a network error in connecting to, writing to or reading from MySQL Fabric. Since 1.6.0.
fabric_sharding_lookup_servers_time_total Time spent connecting to,writing to and reading from MySQL Fabrich during the sharding.lookup_servers remote procedure call. The value is aggregated for all calls. Time is measured in microseconds. Since 1.6.0.
fabric_sharding_lookup_servers_bytes_total Total number of bytes received from MySQL Fabric in reply to sharding.lookup_servers calls. Since 1.6.0.
fabric_sharding_lookup_servers_xml_failure How often a reply from MySQL Fabric to sharding.lookup_servers calls was not understood. Please note, the current experimental implementation does not distinguish between valid errors returned and malformed replies. Since 1.6.0.
xa_begin How many XA/distributed transactions have been started using mysqlnd_ms_xa_begin. Since 1.6.0.
xa_commit_success How many XA/distributed transactions have been successfully committed using mysqlnd_ms_xa_commit. Since 1.6.0.
xa_commit_failure How many XA/distributed transactions failed to commit during mysqlnd_ms_xa_commit. Since 1.6.0.
xa_rollback_success How many XA/distributed transactions have been successfully rolled back using mysqlnd_ms_xa_rollback. The figure does not include implict rollbacks performed as a result of mysqlnd_ms_xa_commit failure. Since 1.6.0.
xa_rollback_failure How many XA/distributed transactions could not be rolled back. This includes failures of mysqlnd_ms_xa_rollback but also failured during rollback when closing a connection, if rollback_on_close is set. Please, see also xa_rollback_on_close below. Since 1.6.0.
xa_participants Total number of participants in any XA transaction started with mysqlnd_ms_xa_begin. Since 1.6.0.
xa_rollback_on_close How many XA transactions have been rolled back implicitly when a connection was close and rollback_on_close is set. Depending on your coding policies, this may hint a flaw in your code as you may prefer to explicitly clean up resources. Since 1.6.0.
pool_masters_total Number of master servers (connections) in the internal connection pool. Since 1.6.0.
pool_slaves_total Number of slave servers (connections) in the internal connection pool. Since 1.6.0.
pool_masters_active Number of master servers (connections) from the internal connection pool which are currently used for picking a connection. Since 1.6.0.
pool_slaves_active Number of slave servers (connections) from the internal connection pool which are currently used for picking a connection. Since 1.6.0.
pool_updates How often the active connection list has been replaced and a new set of master and slave servers had been installed. Since 1.6.0.
pool_master_reactivated How often a master connection has been reused after being flushed from the active list. Since 1.6.0.
pool_slave_reactivated How often a slave connection has been reused after being flushed from the active list. Since 1.6.0.

范例

示例 #1 mysqlnd_ms_get_stats example

<?php
printf("mysqlnd_ms.enable = %d\n", ini_get("mysqlnd_ms.enable"));
printf("mysqlnd_ms.collect_statistics = %d\n", ini_get("mysqlnd_ms.collect_statistics"));
var_dump(mysqlnd_ms_get_stats());
?>

以上例程会输出:

mysqlnd_ms.enable = 1
mysqlnd_ms.collect_statistics = 1
array(26) {
  ["use_slave"]=>
  string(1) "0"
  ["use_master"]=>
  string(1) "0"
  ["use_slave_guess"]=>
  string(1) "0"
  ["use_master_guess"]=>
  string(1) "0"
  ["use_slave_sql_hint"]=>
  string(1) "0"
  ["use_master_sql_hint"]=>
  string(1) "0"
  ["use_last_used_sql_hint"]=>
  string(1) "0"
  ["use_slave_callback"]=>
  string(1) "0"
  ["use_master_callback"]=>
  string(1) "0"
  ["non_lazy_connections_slave_success"]=>
  string(1) "0"
  ["non_lazy_connections_slave_failure"]=>
  string(1) "0"
  ["non_lazy_connections_master_success"]=>
  string(1) "0"
  ["non_lazy_connections_master_failure"]=>
  string(1) "0"
  ["lazy_connections_slave_success"]=>
  string(1) "0"
  ["lazy_connections_slave_failure"]=>
  string(1) "0"
  ["lazy_connections_master_success"]=>
  string(1) "0"
  ["lazy_connections_master_failure"]=>
  string(1) "0"
  ["trx_autocommit_on"]=>
  string(1) "0"
  ["trx_autocommit_off"]=>
  string(1) "0"
  ["trx_master_forced"]=>
  string(1) "0"
  ["gtid_autocommit_injections_success"]=>
  string(1) "0"
  ["gtid_autocommit_injections_failure"]=>
  string(1) "0"
  ["gtid_commit_injections_success"]=>
  string(1) "0"
  ["gtid_commit_injections_failure"]=>
  string(1) "0"
  ["gtid_implicit_commit_injections_success"]=>
  string(1) "0"
  ["gtid_implicit_commit_injections_failure"]=>
  string(1) "0"
  ["transient_error_retries"]=>
  string(1) "0"
}

参见

mysqlnd_ms_match_wild

Finds whether a table name matches a wildcard pattern or not

说明

bool <span class="methodname">mysqlnd_ms_match_wild ( <span class="methodparam">string $table_name , <span class="type">string $wildcard )

Finds whether a table name matches a wildcard pattern or not.

This function is not of much practical relevance with PECL mysqlnd_ms 1.1.0 because the plugin does not support MySQL replication table filtering yet.

参数

table_name
The table name to check if it is matched by the wildcard.

wildcard
The wildcard pattern to check against the table name. The wildcard pattern supports the same placeholders as MySQL replication filters do.

MySQL replication filters can be configured by using the MySQL Server configuration options --replicate-wild-do-table and --replicate-wild-do-db. Please, consult the MySQL Reference Manual to learn more about this MySQL Server feature.

The supported placeholders are:

  • % - zero or more literals
  • _ - one literal

Placeholders can be escaped using \.

返回值

Returns true table_name is matched by wildcard. Otherwise, returns false

范例

示例 #1 mysqlnd_ms_match_wild example

<?php
var_dump(mysqlnd_ms_match_wild("schema_name.table_name", "schema%"));
var_dump(mysqlnd_ms_match_wild("abc", "_"));
var_dump(mysqlnd_ms_match_wild("table1", "table_"));
var_dump(mysqlnd_ms_match_wild("asia_customers", "%customers"));
var_dump(mysqlnd_ms_match_wild("funny%table","funny\%table"));
var_dump(mysqlnd_ms_match_wild("funnytable", "funny%table"));
?>

以上例程会输出:

bool(true)
bool(false)
bool(true)
bool(true)
bool(true)
bool(true)

mysqlnd_ms_query_is_select

查询给定的 SQL 会发送给 master、slave 还是最后使用的 MySQL server 执行。

说明

int <span class="methodname">mysqlnd_ms_query_is_select ( <span class="methodparam">string $query )

查询给定的 SQL 会发送给 master、slave 还是最后使用的 MySQL server 执行。

插件内置的读写分离会分析 SQL,然后决定到底把他发送到哪里执行。这个读写分离器非常 的基本和简单。插件会将所有的查询发送给 master,除非他以 SELECT 开头,或者使用 SQL hints 指定要去 slave 执行。因为这个读写分离很简单, 所以会将一些只读查询发送给主从同步的 master,例如:SHOW TABLES

参数

query
要测试的 SQL 字符串。

返回值

返回 MYSQLND_MS_QUERY_USE_MASTER 说明发送给 master。 返回 MYSQLND_MS_QUERY_USE_SLAVE 说明是一个只读语句, 将发送给 slave 执行。返回 MYSQLND_MS_QUERY_USE_LAST_USED 说明会在上一次执行的服务器连接中执行,这可能是 master 也可能是 slave。

如果通过设定 mysqlnd_ms.disable_rw_split 禁用了读写分离, 那么函数可能返回 MYSQLND_MS_QUERY_USE_MASTER 或者返回 MYSQLND_MS_QUERY_USE_LAST_USED

范例

示例 #1 mysqlnd_ms_query_is_select example

<?php
function is_select($query)
{
 switch (mysqlnd_ms_query_is_select($query))
 {
  case MYSQLND_MS_QUERY_USE_MASTER:
   printf("'%s' should be run on the master.\n", $query);
   break;
  case MYSQLND_MS_QUERY_USE_SLAVE:
   printf("'%s' should be run on a slave.\n", $query);
   break;
  case MYSQLND_MS_QUERY_USE_LAST_USED:
   printf("'%s' should be run on the server that has run the previous query\n", $query);
   break;
  default:
   printf("No suggestion where to run the '%s', fallback to master recommended\n", $query);
   break;
 }
}

is_select("INSERT INTO test(id) VALUES (1)");
is_select("SELECT 1 FROM DUAL");
is_select("/*" . MYSQLND_MS_LAST_USED_SWITCH . "*/SELECT 2 FROM DUAL");
?>

以上例程会输出:

INSERT INTO test(id) VALUES (1) should be run on the master.
SELECT 1 FROM DUAL should be run on a slave.
/*ms=last_used*/SELECT 2 FROM DUAL should be run on the server that has run the previous query

参见

mysqlnd_ms_set_qos

Sets the quality of service needed from the cluster

说明

bool <span class="methodname">mysqlnd_ms_set_qos ( <span class="methodparam">mixed $connection , int $service_level [, <span class="type">int $service_level_option [, <span class="methodparam">mixed $option_value ]] )

Sets the quality of service needed from the cluster. A database cluster delivers a certain quality of service to the user depending on its architecture. A major aspect of the quality of service is the consistency level the cluster can offer. An asynchronous MySQL replication cluster defaults to eventual consistency for slave reads: a slave may serve stale data, current data, or it may have not the requested data at all, because it is not synchronous to the master. In a MySQL replication cluster, only master accesses can give strong consistency, which promises that all clients see each others changes.

PECL/mysqlnd_ms hides the complexity of choosing appropriate nodes to achieve a certain level of service from the cluster. The "Quality of Service" filter implements the necessary logic. The filter can either be configured in the plugins configuration file, or at runtime using <span class="function">mysqlnd_ms_set_qos.

Similar results can be achieved with PECL mysqlnd_ms \< 1.2.0, if using SQL hints to force the use of a certain type of node or using the master_on_write plugin configuration option. The first requires more code and causes more work on the application side. The latter is less refined than using the quality of service filter. Settings made through the function call can be reversed, as shown in the example below. The example temporarily switches to a higher service level (session consistency, read your writes) and returns back to the clusters default after it has performed all operations that require the better service. This way, read load on the master can be minimized compared to using master_on_write, which would continue using the master after the first write.

Since 1.5.0 calls will fail when done in the middle of a transaction if transaction stickiness is enabled and transaction boundaries have been detected. properly.

参数

connection
A PECL/mysqlnd_ms connection handle to a MySQL server of the type PDO_MYSQL, mysqli or ext/mysql for which a service level is to be set. The connection handle is obtained when opening a connection with a host name that matches a mysqlnd_ms configuration file entry using any of the above three MySQL driver extensions.

service_level
The requested service level: MYSQLND_MS_QOS_CONSISTENCY_EVENTUAL, MYSQLND_MS_QOS_CONSISTENCY_SESSION or MYSQLND_MS_QOS_CONSISTENCY_STRONG.

service_level_option
An option to parameterize the requested service level. The option can either be MYSQLND_MS_QOS_OPTION_GTID or MYSQLND_MS_QOS_OPTION_AGE.

The option MYSQLND_MS_QOS_OPTION_GTID can be used to refine the service level MYSQLND_MS_QOS_CONSISTENCY_SESSION. It must be combined with a fourth function parameter, the option_value. The option_value shall be a global transaction ID obtained from <span class="function">mysqlnd_ms_get_last_gtid. If set, the plugin considers both master servers and asynchronous slaves for session consistency (read your writes). Otherwise, only masters are used to achieve session consistency. A slave is considered up-to-date and checked if it has already replicated the global transaction ID from option_value. Please note, searching appropriate slaves is an expensive and slow operation. Use the feature sparsely, if the master cannot handle the read load alone.

The MYSQLND_MS_QOS_OPTION_AGE option can be combined with the MYSQLND_MS_QOS_CONSISTENCY_EVENTUAL service level, to filter out asynchronous slaves that lag more seconds behind the master than option_value. If set, the plugin will only consider slaves for reading if SHOW SLAVE STATUS reports Slave_IO_Running=Yes, Slave_SQL_Running=Yes and Seconds_Behind_Master \<= option_value. Please note, searching appropriate slaves is an expensive and slow operation. Use the feature sparsely in version 1.2.0. Future versions may improve the algorithm used to identify candidates. Please, see the MySQL reference manual about the precision, accuracy and limitations of the MySQL administrative command SHOW SLAVE STATUS.

option_value
Parameter value for the service level option. See also the service_level_option parameter.

返回值

Returns true if the connections service level has been switched to the requested. Otherwise, returns false

注释

Note:

mysqlnd_ms_set_qos requires PHP >= 5.4.0 and PECL mysqlnd_ms >= 1.2.0. Internally, it is using a mysqlnd library C functionality not available with PHP 5.3.

Please note, all MySQL 5.6 production versions do not provide clients with enough information to use GTIDs for enforcing session consistency. In the worst case, the plugin will choose the master only.

范例

示例 #1 mysqlnd_ms_set_qos example

<?php
/* Open mysqlnd_ms connection using mysqli, PDO_MySQL or mysql extension */
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* Session consistency: read your writes */
$ret = mysqlnd_ms_set_qos($mysqli, MYSQLND_MS_QOS_CONSISTENCY_SESSION);
if (!$ret)
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

/* Will use master and return fresh data, client can see his last write */
if (!$res = $mysqli->query("SELECT item, price FROM orders WHERE order_id = 1"))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

/* Back to default: use of all slaves and masters permitted, stale data can happen */
if (!mysqlnd_ms_set_qos($mysqli, MYSQLND_MS_QOS_CONSISTENCY_EVENTUAL))
  die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
?>

参见

mysqlnd_ms_set_user_pick_server

Sets a callback for user-defined read/write splitting

说明

bool <span class="methodname">mysqlnd_ms_set_user_pick_server ( <span class="methodparam">string $function )

Sets a callback for user-defined read/write splitting. The plugin will call the callback only if pick[]=user is the default rule for server picking in the relevant section of the plugins configuration file.

The plugins built-in read/write query split mechanism decisions can be overwritten in two ways. The easiest way is to prepend the query string with the SQL hints MYSQLND_MS_MASTER_SWITCH, MYSQLND_MS_SLAVE_SWITCH or MYSQLND_MS_LAST_USED_SWITCH. Using SQL hints one can control, for example, whether a query shall be send to the MySQL replication master server or one of the slave servers. By help of SQL hints it is not possible to pick a certain slave server for query execution.

Full control on server selection can be gained using a callback function. Use of a callback is recommended to expert users only because the callback has to cover all cases otherwise handled by the plugin.

The plugin will invoke the callback function for selecting a server from the lists of configured master and slave servers. The callback function inspects the query to run and picks a server for query execution by returning the hosts URI, as found in the master and slave list.

If the lazy connections are enabled and the callback chooses a slave server for which no connection has been established so far and establishing the connection to the slave fails, the plugin will return an error upon the next action on the failed connection, for example, when running a query. It is the responsibility of the application developer to handle the error. For example, the application can re-run the query to trigger a new server selection and callback invocation. If so, the callback must make sure to select a different slave, or check slave availability, before returning to the plugin to prevent an endless loop.

参数

function
The function to be called. Class methods may also be invoked statically using this function by passing array($classname, $methodname) to this parameter. Additionally class methods of an object instance may be called by passing array($objectinstance, $methodname) to this parameter.

返回值

Host to run the query on. The host URI is to be taken from the master and slave connection lists passed to the callback function. If callback returns a value neither found in the master nor in the slave connection lists the plugin will fallback to the second pick method configured via the pick[] setting in the plugin configuration file. If not second pick method is given, the plugin falls back to the build-in default pick method for server selection.

注释

Note:

mysqlnd_ms_set_user_pick_server is available with PECL mysqlnd_ms \< 1.1.0. It has been replaced by the user filter. Please, check the Change History for upgrade notes.

范例

示例 #1 <span class="function">mysqlnd_ms_set_user_pick_server example

[myapp]
master[] = localhost
slave[] = 192.168.2.27:3306
slave[] = 192.168.78.136:3306
pick[] = user
<?php

function pick_server($connected, $query, $master, $slaves, $last_used)
{
 static $slave_idx = 0;
 static $num_slaves = NULL;
 if (is_null($num_slaves))
  $num_slaves = count($slaves);

 /* default: fallback to the plugins build-in logic */
 $ret = NULL;

 printf("User has connected to '%s'...\n", $connected);
 printf("... deciding where to run '%s'\n", $query);

 $where = mysqlnd_ms_query_is_select($query);
 switch ($where)
 {
  case MYSQLND_MS_QUERY_USE_MASTER:
   printf("... using master\n");
   $ret = $master[0];
   break;
  case MYSQLND_MS_QUERY_USE_SLAVE:
   /* SELECT or SQL hint for using slave */
   if (stristr($query, "FROM table_on_slave_a_only"))
   {
    /* a table which is only on the first configured slave  */
    printf("... access to table available only on slave A detected\n");
    $ret = $slaves[0];
   }
   else
   {
    /* round robin */
    printf("... some read-only query for a slave\n");
    $ret = $slaves[$slave_idx++ % $num_slaves];
   }
   break;
  case MYSQLND_MS_QUERY_LAST_USED:
   printf("... using last used server\n");
   $ret = $last_used;
   break;
 }

 printf("... ret = '%s'\n", $ret);
 return $ret;
}

mysqlnd_ms_set_user_pick_server("pick_server");

$mysqli = new mysqli("myapp", "root", "root", "test");

if (!($res = $mysqli->query("SELECT 1 FROM DUAL")))
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
else
 $res->close();

if (!($res = $mysqli->query("SELECT 2 FROM DUAL")))
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
else
 $res->close();


if (!($res = $mysqli->query("SELECT * FROM table_on_slave_a_only")))
 printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
else
 $res->close();

$mysqli->close();
?>

以上例程会输出:

User has connected to 'myapp'...
... deciding where to run 'SELECT 1 FROM DUAL'
... some read-only query for a slave
... ret = 'tcp://192.168.2.27:3306'
User has connected to 'myapp'...
... deciding where to run 'SELECT 2 FROM DUAL'
... some read-only query for a slave
... ret = 'tcp://192.168.78.136:3306'
User has connected to 'myapp'...
... deciding where to run 'SELECT * FROM table_on_slave_a_only'
... access to table available only on slave A detected
... ret = 'tcp://192.168.2.27:3306'

参见

mysqlnd_ms_xa_begin

Starts a distributed/XA transaction among MySQL servers

说明

int <span class="methodname">mysqlnd_ms_xa_begin ( <span class="methodparam">mixed $connection , string $gtrid [, <span class="type">int $timeout ] )

Starts a XA transaction among MySQL servers. PECL/mysqlnd_ms acts as a transaction coordinator the distributed transaction.

Once a global transaction has been started, the plugin injects appropriate XA BEGIN SQL statements on all MySQL servers used in the following. The global transaction is either ended by calling <span class="function">mysqlnd_ms_xa_commit, <span class="function">mysqlnd_ms_xa_rollback or by an implicit rollback in case of an error.

During a global transaction, the plugin tracks all server switches, for example, when switching from one MySQL shard to another MySQL shard. Immediately before a query is run on a server that has not been participating in the global transaction yet, XA BEGIN is executed on the server. From a users perspective the injection happens during a call to a query execution function such as <span class="function">mysqli_query. Should the injection fail an error is reported to the caller of the query execution function. The failing server does not become a participant in the global transaction. The user may retry executing a query on the server and hereby retry injecting XA BEGIN, abort the global transaction because not all required servers can participate, or ignore and continue the global without the failed server.

Reasons to fail executing XA BEGIN include but are not limited to a server being unreachable or the server having an open, concurrent XA transaction using the same xid.

Please note, global and local transactions are mutually exclusive. You cannot start a XA transaction when you have a local transaction open. The local transaction must be ended first. The plugin tries to detect this conflict as early as possible. It monitors API calls for controlling local transactions to learn about the current state. However, if using SQL statements for local transactions such as BEGIN, the plugin may not know the current state and the conflict is not detected before XA BEGIN is injected and executed.

The use of other XA resources but MySQL servers is not supported by the function. To carry out a global transaction among, for example, a MySQL server and another vendors database system, you should issue the systems SQL commands yourself.

Note: Experimental

The feature is currently under development. There may be issues and/or feature limitations. Do not use in production environments.

参数

connection
A MySQL connection handle obtained from any of the connect functions of the mysqli, mysql or PDO_MYSQL extensions.

gtrid
Global transaction identifier (gtrid). The gtrid is a binary string up to 64 bytes long. Please note, depending on your character set settings, 64 characters may require more than 64 bytes to store.

In accordance with the MySQL SQL syntax, XA transactions use identifiers made of three parts. An xid consists of a global transaction identifier (gtrid), a branch qualifier (bqual) and a format identifier (formatID). Only the global transaction identifier can and needs to be set.

The branch qualifier and format identifier are set automatically. The details should be considered implementation dependent, which may change without prior notice. In version 1.6 the branch qualifier is consecutive number which is incremented whenever a participant joins the global transaction.

timeout
Timeout in seconds. The default value is 60 seconds.

The timeout is a hint to the garbage collection. If a transaction is recorded to take longer than expected, the garbage collection begins checking the transactions status.

Setting a low value may make the garbage collection check the progress too often. Please note, checking the status of a global transaction may involve connecting to all recorded participants and possibly issuing queries on the servers.

返回值

Returns true if there is no open local or global transaction and a new global transaction can be started. Otherwise, returns false

参见

mysqlnd_ms_xa_commit

Commits a distributed/XA transaction among MySQL servers

说明

bool <span class="methodname">mysqlnd_ms_xa_commit ( <span class="methodparam">mixed $connection , string $gtrid )

Commits a global transaction among MySQL servers started by <span class="function">mysqlnd_ms_xa_begin.

If any of the global transaction participants fails to commit an implicit rollback is performed. It may happen that not all cases can be handled during the rollback. For example, no attempts will be made to reconnect to a participant after the connection to the participant has been lost. Solving cases that cannot easily be rolled back is left to the garbage collection.

Note: Experimental

The feature is currently under development. There may be issues and/or feature limitations. Do not use in production environments.

参数

connection
A MySQL connection handle obtained from any of the connect functions of the mysqli, mysql or PDO_MYSQL extensions.

gtrid
Global transaction identifier (gtrid).

返回值

Returns true if the global transaction has been committed. Otherwise, returns false

参见

mysqlnd_ms_xa_gc

Garbage collects unfinished XA transactions after severe errors

说明

int <span class="methodname">mysqlnd_ms_xa_gc ( <span class="methodparam">mixed $connection [, string $gtrid [, <span class="type">bool $ignore_max_retries ]] )

Garbage collects unfinished XA transactions.

The XA protocol is a blocking protocol. There exist cases when servers participating in a global transaction cannot make progress when the transaction coordinator crashes or disconnects. In such a case, the MySQL servers keep waiting for instructions to finish the XA transaction in question. Because transactions occupy resources, transactions should always be terminated properly.

Garbage collection requires configuring a state store to track global transactions. Should a PHP client crash in the middle of a transaction and a new PHP client be started, then the built-in garbage collection can learn about the aborted global transaction and terminate it. If you do not configure a state store, the garbage collection cannot perform any cleanup tasks.

The state store should be crash-safe and be highly available to survive its own crash. Currently, only MySQL is supported as a state store.

Garbage collection can also be performed automatically in the background. See the plugin configuration directive garbage_collection for details.

Note: Experimental

The feature is currently under development. There may be issues and/or feature limitations. Do not use in production environments.

参数

connection
A MySQL connection handle obtained from any of the connect functions of the mysqli, mysql or PDO_MYSQL extensions.

gtrid
Global transaction identifier (gtrid). If given, the garbage collection considers the transaction only. Otherwise, the state store is scanned for any unfinished transaction.

ignore_max_retries
Whether to ignore the plugin configuration max_retries setting. If garbage collection continuously fails and the max_retries limit is reached prior to finishing the failed global transaction, you can attempt further runs prior to investigating the cause and solving the issue manually by issuing appropriate SQL statements on the participants. Setting the parameter has the same effect as temporarily setting max_retries = 0.

返回值

Returns true if garbage collection was successful. Otherwise, returns false

参见

mysqlnd_ms_xa_rollback

Rolls back a distributed/XA transaction among MySQL servers

说明

int <span class="methodname">mysqlnd_ms_xa_rollback ( <span class="methodparam">mixed $connection , string $gtrid )

Rolls back a global transaction among MySQL servers started by <span class="function">mysqlnd_ms_xa_begin.

If any of the global transaction participants fails to rollback the situation is left to be solved by the garbage collection.

Note: Experimental

The feature is currently under development. There may be issues and/or feature limitations. Do not use in production environments.

参数

connection
A MySQL connection handle obtained from any of the connect functions of the mysqli, mysql or PDO_MYSQL extensions.

gtrid
Global transaction identifier (gtrid).

返回值

Returns true if the global transaction has been rolled back. Otherwise, returns false

参见

目录

Change History

目录

This change history is a high level summary of selected changes that may impact applications and/or break backwards compatibility.

See also the CHANGES file in the source distribution for a complete list of changes.

PECL/mysqlnd_ms 1.6 series

1.6.0-alpha

  • Release date: TBD
  • Motto/theme: Maintenance and initial MySQL Fabric support

Note:

This is the current development series. All features are at an early stage. Changes may happen at any time without prior notice. Please, do not use this version in production environments.

The documentation may not reflect all changes yet.

Bug fixes

  • Won't fix: #66616 R/W split fails: QOS with mysqlnd_get_last_gtid with built-in MySQL GTID

    This is not a bug in the plugins implementation but a server side feature limitation not considered and documented before. MySQL 5.6 built-in GTIDs cannot be used to ensure session consistency when reading from slaves in all cases. In the worst case the plugin will not consider using the slaves and fallback to using the master. There will be no wrong results but no benefit from doing GTID checks either.

  • Fixed #66064 - Random once load balancer ignoring weights

    Due to a config parsing bug random load balancing has ignored node weights if, and only if, the sticky flag was set (random once).

  • Fixed #65496 - Wrong check for slave delay

    The quality of service filter has erroneously ignored slaves that lag for zero (0) seconds if a any maximum lag had been set. Although a slave was not lagging behind, it was excluded from the load balancing list if a maximum age was set by the QoS filter. This was due to using the wrong comparison operator in the source of the filter.

  • Fixed #65408 - Compile failure with -Werror=format-security

Feature changes

  • Introduced an internal connection pool. When using Fabric and switching from shard group A to shard group B, we are replacing the entire list of masters and slaves. This troubles the connections state alignment logic and some filters. Some filters cache information on the master and slave lists. The new internal connection pool abstraction allows us to inform the filters of changes, hence they can update their caches.

    Later on, the pool can also be used to reduce connection overhead. Assume you are switching from a shard group to another and back again. Whenever the switch is done, the pool's active server (and connection) lists are replaced. However, no longer used connections are not necessarily closed immediately but can be kept in the pool for later reuse.

    Please note, the connection pool is internalat this point. There are some new statistics to monitor it. However, you cannot yet configure pool size of behaviour.

  • Added a basic distributed transaction abstraction. XA transactions can are supported ever since using standard SQL calls. This is inconvenient as XA participants must be managed manually. PECL/mysqlnd_ms introduces API calls to control XA transaction among MySQL servers. When using the new functions, PECL/mysqlnd_ms acts as a transaction coordinator. After starting a distributed transaction, the plugin tracks all servers involved until the transaction is ended and issues appropriate SQL statements on the XA participants.

    This is useful, for example, when using Fabric and sharding. When using Fabric the actual shard servers involved in a business transaction may not be known in advance. Thus, manually controlling a transaction that spawns multiple shards becomes difficult. Please, be warned about current limitations.

  • Introduced automatic retry loop for transient errors and corresponding statistic to count the number of implicit retries. Some distributed database clusters use transient errors to hint a client to retry its operation in a bit. Most often, the client is then supposed to halt execution (sleep) for a short moment before retrying the desired operation. Immediately failing over to another node is not necessary in response to the error. Instead, a retry loop can be performed. Common situation when using MySQL Cluster.

  • Introduced automatic retry loop for transient errors and corresponding statistic to count the number of implicit retries. Some distributed database clusters use transient errors to hint a client to retry its operation in a bit. Most often, the client is then supposed to halt execution (sleep) for a short moment before retrying the desired operation. Immediately failing over to another node is not necessary in response to the error. Instead, a retry loop can be performed. Common situation when using MySQL Cluster.

  • Introduced most basic support for the MySQL Fabric High Availability and sharding framework.

    Please, consider this pre-alpha quality. Both the server side framework and the client side code is supposed to work flawless considering the MySQL Fabric quickstart examples only. However, testing has not been performed to the level of prior plugin alpha releases. Either sides are moving targets, API changes may happen at any time without prior warning.

    As this is work in progress, the manual may not yet reflect allow feature limitations and known bugs.

  • New statistics to monitor the Fabric XML RPC call sharding.lookup_servers: fabric_sharding_lookup_servers_success, fabric_sharding_lookup_servers_failure, fabric_sharding_lookup_servers_time_total, fabric_sharding_lookup_servers_bytes_total, fabric_sharding_lookup_servers_xml_failure.

  • New functions related to MySQL Fabric: <span class="function">mysqlnd_ms_fabric_select_shard, <span class="function">mysqlnd_ms_fabric_select_global, <span class="function">mysqlnd_ms_dump_servers.

PECL/mysqlnd_ms 1.5 series

1.5.1-stable

  • Release date: 06/2013
  • Motto/theme: Sharding support, improved transaction support

Note:

This is the current stable series. Use this version in production environments.

The documentation is complete.

1.5.0-alpha

  • Release date: 03/2013
  • Motto/theme: Sharding support, improved transaction support

Bug fixes

  • Fixed #60605 PHP segmentation fault when mysqlnd_ms is enabled.

  • Setting transaction stickiness disables all load balancing, including automatic failover, for the duration of a transaction. So far connection switches could have happened in the middle of a transaction in multi-master configurations and during automatic failover although transaction monitoring had detected transaction boundaries properly.

  • BC break and bug fix. SQL hints enforcing the use of a specific kind of server (MYSQLND_MS_MASTER_SWITCH, MYSQLND_MS_SLAVE_SWITCH, MYSQLND_MS_LAST_USED_SWITCH) are ignored for the duration of a transaction of transaction stickiness is enabled and transaction boundaries have been detected properly.

    This is a change in behaviour. However, it is also a bug fix and a step to align behaviour. If, in previous versions, transaction stickiness, one of the above listed SQL hints and the quality of service filtering was combined it could happened that the SQL hints got ignored. In some case the SQL hints did work, in other cases they did not. The new behaviour is more consistent. SQL hints will always be ignore for the duration of a transaction, if transaction stickiness is enabled.

    Please note, transaction boundary detection continues to be based on API call monitoring. SQL commands controlling transactions are not monitored.

  • BC break and bug fix. Calls to <span class="function">mysqlnd_ms_set_qos will fail when done in the middle of a transaction if transaction stickiness is enabled. Connection switches are not allowed for the duration of a transaction. Changing the quality of service likely results on a different set of servers qualifying for query execution, possibly making it necessary to switch connections. Thus, the call is not allowed in during an active transaction. The quality of server can, however, be changed in between transactions.

Feature changes

  • Introduced the node_group filter. The filter lets you organize servers (master and slaves) into groups. Queries can be directed to a certain group of servers by prefixing the query statement with a SQL hint/comment that contains the groups configured name. Grouping can be used for partitioning and sharding, and also to optimize for local caching. In the case of sharding, a group name can be thought of like a shard key. All queries for a given shard key will be executed on the configured shard. Note: both the client and server must support sharding for sharding to function with mysqlnd_ms.

  • Extended configuration file validation during PHP startup (RINIT). An E_WARNING level error will be thrown if the configuration file can not be read (permissions), is empty, or the file (JSON) could not be parsed. Warnings may appear in log files, which depending on how PHP is configured.

    Distributions that aim to provide a pre-configured setup, including a configuration file stub, are asked to put {} into the configuration file to prevent this warning about an invalid configuration file.

    Further configuration file validation is done when parsing sections upon opening a connection. Please, note that there may still be situations when an invalid plugin configuration file does not lead to proper error messages but a failure to connect.

  • As of PHP 5.5.0, improved support for transaction boundaries detection was added for mysqli. The mysqli extension has been modified to use the new C API calls of the mysqlnd library to begin, commit, and rollback a transaction or savepoint. If trx_stickiness is used to enable transaction aware load balancing, the <span class="function">mysqli_begin, <span class="function">mysqli_commit and <span class="function">mysqli_rollback functions will now be monitered by the plugin, to go along with the <span class="function">mysqli_autocommit function that was already supported. All SQL features to control transactions are also available through the improved mysqli transaction control related functions. This means that it is not required to issue SQL statements instead of using API calls. Applications using the appropriate API calls can be load balanced by PECL/mysqlnd_ms in a completely transaction-aware way.

    Please note, PDO_MySQL has not been updated yet to utilize the new mysqlnd API calls. Thus, transaction boundary detection with PDO_MySQL continues to be limited to the monitoring by passing in PDO::ATTR_AUTOCOMMIT to <span class="methodname">PDO::setAttribute.

  • Introduced trx_stickiness=on. This trx_stickiness option differs from trx_stickiness=master as it tries to execute a read-only transaction on a slave, if quality of service (consistency level) allows the use of a slave. Read-only transactions were introduced in MySQL 5.6, and they offer performance gains.

  • Query cache support is considered beta if used with the mysqli API. It should work fine with primary copy based clusters. For all other APIs, this feature continues to be called experimental.

  • The code examples in the mysqlnd_ms source were updated.

PECL/mysqlnd_ms 1.4 series

1.4.2-stable

  • Release date: 08/2012
  • Motto/theme: Tweaking based on user feedback

1.4.1-beta

  • Release date: 08/2012
  • Motto/theme: Tweaking based on user feedback

Bug fixes

  • Fixed build with PHP 5.5

1.4.0-alpha

  • Release date: 07/2012
  • Motto/theme: Tweaking based on user feedback

Feature changes

  • BC break: Renamed plugin configuration setting ini_file to config_file. In early versions the plugin configuration file used ini style. Back then the configuration setting was named accordingly. It has now been renamed to reflect the newer file format and to distinguish it from PHP's own ini file (configuration directives file).

  • Introduced new default charset setting server_charset to allow proper escaping before a connection is opened. This is most useful when using lazy connections, which are a default.

  • Introduced wait_for_gtid_timeout setting to throttle slave reads that need session consistency. If global transaction identifier are used and the service level is set to session consistency, the plugin tries to find up-to-date slaves. The slave status check is done by a SQL statement. If nothing else is set, the slave status is checked only one can the search for more up-to-date slaves continues immediately thereafter. Setting wait_for_gtid_timeout instructs the plugin to poll a slaves status for wait_for_gtid_timeout seconds if the first execution of the SQL statement has shown that the slave is not up-to-date yet. The poll will be done once per second. This way, the plugin will wait for slaves to catch up and throttle the client.

  • New failover strategy loop_before_master. By default the plugin does no failover. It is possible to enable automatic failover if a connection attempt fails. Upto version 1.3 only master strategy existed to failover to a master if a slave connection fails. loop_before_master is similar but tries all other slaves before attempting to connect to the master if a slave connection fails.

    The number of attempts can be limited using the max_retries option. Failed hosts can be remembered and skipped in load balancing for the rest of the web request. max_retries and remember_failed are considered experimental although decent stability is given. Syntax and semantics may change in the future without prior notice.

PECL/mysqlnd_ms 1.3 series

1.3.2-stable

  • Release date: 04/2012
  • Motto/theme: see 1.3.0-alpha

Bug fixes

  • Fixed problem with multi-master where although in a transaction the queries to the master weren't sticky and were spread all over the masters (RR). Still not sticky for Random. Random_once is not affected.

1.3.1-beta

  • Release date: 04/2012
  • Motto/theme: see 1.3.0-alpha

Bug fixes

  • Fixed problem with building together with QC.

1.3.0-alpha

  • Release date: 04/2012
  • Motto/theme: Query caching through quality-of-service concept

The 1.3 series aims to improve the performance of applications and the overall load of an asynchronous MySQL cluster, for example, a MySQL cluster using MySQL Replication. This is done by transparently replacing a slave access with a local cache access, if the application allows it by setting an appropriate quality of service flag. When using MySQL replication a slave can serve stale data. An application using MySQL replication must continue to work correctly with stale data. Given that the application is know to work correctly with stale data, the slave access can transparently be replace with a local cache access.

PECL/mysqlnd_qc serves as a cache backend. PECL/mysqlnd_qc supports use of various storage locations, among others main memory, APC and MEMCACHE.

Feature changes

  • Added cache option to quality-of-service (QoS) filter.

    • New configure option enable-mysqlnd-ms-cache-support
    • New constant MYSQLND_MS_HAVE_CACHE_SUPPORT.
    • New constant MYSQLND_MS_QOS_OPTION_CACHE to be used with <span class="function">mysqlnd_ms_set_qos.
  • Support for built-in global transaction identifier feature of MySQL 5.6.5-m8 or newer.

PECL/mysqlnd_ms 1.2 series

1.2.1-beta

  • Release date: 01/2012
  • Motto/theme: see 1.2.0-alpha

Minor test changes.

1.2.0-alpha

  • Release date: 11/2011
  • Motto/theme: Global Transaction ID injection and quality-of-service concept

In version 1.2 the focus continues to be on supporting MySQL database clusters with asynchronous replication. The plugin tries to make using the cluster introducing a quality-of-service filter which applications can use to define what service quality they need from the cluster. Service levels provided are eventual consistency with optional maximum age/slave slag, session consistency and strong consistency.

Additionally the plugin can do client-side global transaction id injection to make manual master failover easier.

Feature changes

  • Introduced quality-of-service (QoS) filter. Service levels provided by QoS filter:

    • eventual consistency, optional option slave lag
    • session consistency, optional option GTID
    • strong consistency
  • Added the mysqlnd_ms_set_qos function to set the required connection quality at runtime. The new constants related to <span class="function">mysqlnd_ms_set_qos are:

    • MYSQLND_MS_QOS_CONSISTENCY_STRONG
    • MYSQLND_MS_QOS_CONSISTENCY_SESSION
    • MYSQLND_MS_QOS_CONSISTENCY_EVENTUAL
    • MYSQLND_MS_QOS_OPTION_GTID
    • MYSQLND_MS_QOS_OPTION_AGE
  • Added client-side global transaction id injection (GTID).

  • New statistics related to GTID:

    • gtid_autocommit_injections_success
    • gtid_autocommit_injections_failure
    • gtid_commit_injections_success
    • gtid_commit_injections_failure
    • gtid_implicit_commit_injections_success
    • gtid_implicit_commit_injections_failure
  • Added mysqlnd_ms_get_last_gtid to fetch the last global transaction id.

  • Enabled support for multi master without slaves.

PECL/mysqlnd_ms 1.1 series

1.1.0

  • Release date: 09/2011
  • Motto/theme: Cover replication basics with production quality

The 1.1 and 1.0 series expose a similar feature set. Internally, the 1.1 series has been refactored to plan for future feature additions. A new configuration file format has been introduced, and limitations have been lifted. And the code quality and quality assurance has been improved.

Feature changes

  • Added the (chainable) filter concept:

    • BC break: <span class="function">mysqlnd_ms_set_user_pick_server has been removed. Thehttp://svn.php.net/viewvc/pecl/mysqlnd_ms/trunk/ user filter has been introduced to replace it. The filter offers similar functionality, but see below for an explanation of the differences.
  • New powerful JSON based configuration syntax.

  • Lazy connections improved: security relevant, and state changing commands are covered.

  • Support for (native) prepared statements.

  • New statistics: use_master_guess, use_slave_guess.

    • BC break: Semantics of statistics changed for use_slave, use_master. Future changes are likely. Please see, <span class="function">mysqlnd_ms_get_stats.
  • List of broadcasted messages extended by ssl_set.

  • Library calls now monitored to remember settings for lazy connections: change_user, select_db, set_charset, set_autocommit.

  • Introduced mysqlnd_ms.disable_rw_split. The configuration setting allows using the load balancing and lazy connection functionality independently of read write splitting.

Bug fixes

  • Fixed PECL #22724 - Server switching (mysqlnd_ms_query_is_select() case sensitive)
  • Fixed PECL #22784 - Using mysql_connect and mysql_select_db did not work
  • Fixed PECL #59982 - Unusable extension with --enable-mysqlnd-ms-table-filter. Use of the option is NOT supported. You must not used it. Added note to m4.
  • Fixed Bug #60119 - host="localhost" lost in mysqlnd_ms_get_last_used_connection()

The mysqlnd_ms_set_user_pick_server function was removed, and replaced in favor of a new user filter. You can no longer set a callback function using <span class="function">mysqlnd_ms_set_user_pick_server at runtime, but instead have to configure it in the plugins configuration file. The user filter will pass the same arguments to the callback as before. Therefore, you can continue to use the same procedural function as a callback.callback It is no longer possible to use static class methods, or class methods of an object instance, as a callback. Doing so will cause the function executing a statement handled by the plugin to emit an E_RECOVERABLE_ERROR level error, which might look like: "(mysqlnd_ms) Specified callback (picker) is not a valid callback." Note: this may halt your application.

PECL/mysqlnd_ms 1.0 series

1.0.1-alpha

  • Release date: 04/2011
  • Motto/theme: bug fix release

1.0.0-alpha

  • Release date: 04/2011
  • Motto/theme: Cover replication basics to test user feedback

The first release of practical use. It features basic automatic read-write splitting, SQL hints to overrule automatic redirection, load balancing of slave requests, lazy connections, and optional, automatic use of the master after the first write.

The public feature set is close to that of the 1.1 release.

1.0.0-pre-alpha

  • Release date: 09/2010
  • Motto/theme: Proof of concept

Initial check-in. Essentially a demo of the mysqlnd plugin API.

Mysqlnd query result cache plugin

目录

The mysqlnd query result cache plugin adds easy to use client-side query caching to all PHP MySQL extensions using mysqlnd.

As of version PHP 5.3.3 the MySQL native driver for PHP ( mysqlnd) features an internal plugin C API. C plugins, such as the query cache plugin, can extend the functionality of mysqlnd.

Mysqlnd plugins such as the query cache plugin operate transparent from a user perspective. The cache plugin supports all PHP applications and all PHP MySQL extensions ( mysqli, mysql, PDO_MYSQL). It does not change existing APIs.

No significant application changes are required to cache a query. The cache has two operation modes. It will either cache all queries (not recommended) or only those queries marked with a certain SQL hint (recommended).

Key Features

  • Transparent and therefore easy to use

    • supports all PHP MySQL extensions

    • no API changes

    • very little application changes required

  • Flexible invalidation strategy

    • Time-to-Live (TTL)

    • user-defined

  • Storage with different scope and life-span

    • Default (Hash, process memory)

    • APC

    • MEMCACHE

    • sqlite

    • user-defined

  • Built-in slam defense to prevent cache stampeding.

Limitations

The current 1.0.1 release of PECL mysqlnd_qc does not support PHP 5.4. Version 1.1.0-alpha lifts this limitation.

Prepared statements and unbuffered queries are fully supported. Thus, the plugin is capable of caching all statements issued with mysqli or PDO_MySQL, which are the only two PHP MySQL APIs to offer prepared statement support.

On the name

The shortcut mysqlnd_qc stands for mysqlnd query cache plugin. The name was chosen for a quick-and-dirty proof-of-concept. In the beginning the developers did not expect to continue using the code base. Sometimes PECL/mysqlnd_qc has also been called client-side query result set cache.

Quickstart and Examples

目录

The mysqlnd query cache plugin is easy to use. This quickstart will demo typical use-cases, and provide practical advice on getting started.

It is strongly recommended to read the reference sections in addition to the quickstart. It is safe to begin with the quickstart. However, before using the plugin in mission critical environments we urge you to read additionally the background information from the reference sections.

Most of the examples use the mysqli extension because it is the most feature complete PHP MySQL extension. However, the plugin can be used with any PHP MySQL extension that is using the mysqlnd library.

Architecture and Concepts

The query cache plugin is implemented as a PHP extension. It is written in C and operates under the hood of PHP. During the startup of the PHP interpreter, it gets registered as a mysqlnd plugin to replace selected mysqlnd C methods. Hereby, it can change the behaviour of any PHP MySQL extension (mysqli, PDO_MYSQL, mysql) compiled to use the mysqlnd library without changing the extensions API. This makes the plugin compatible with each and every PHP MySQL application. Because existing APIs are not changed, it is almost transparent to use. Please, see the mysqlnd plugin API description for a discussion of the advantages of the plugin architecture and a comparison with proxy based solutions.

Transparent to use

At PHP run time PECL/mysqlnd_qc can proxy queries send from PHP (mysqlnd) to the MySQL server. It then inspects the statement string to find whether it shall cache its results. If so, result set is cached using a storage handler and further executions of the statement are served from the cache for a user-defined period. The Time to Live (TTL) of the cache entry can either be set globally or on a per statement basis.

A statement is either cached if the plugin is instructed to cache all statements globally using a or, if the query string starts with the SQL hint (/*qc=on*/). The plugin is capable of caching any query issued by calling appropriate API calls of any of the existing PHP MySQL extensions.

Flexible storage: various storage handler

Various storage handler are supported to offer different scopes for cache entries. Different scopes allow for different degrees in sharing cache entries among clients.

  • default (built-in): process memory, scope: process, one or more web requests depending on PHP deployment model used

  • APC: shared memory, scope: single server, multiple web requests

  • SQLite: memory or file, scope: single server, multiple web requests

  • MEMCACHE: main memory, scope: single or multiple server, multiple web requests

  • user (built-in): user-defined - any, scope: user-defined - any

Support for the APC, SQLite and MEMCACHE storage handler has to be enabled at compile time. The default and user handler are built-in. It is possible to switch between compiled-in storage handlers on a per query basis at run time. However, it is recommended to pick one storage handler and use it for all cache entries.

Built-in slam defense to avoid overloading

To avoid overload situations the cache plugin has a built-in slam defense mechanism. If a popular cache entries expires many clients using the cache entries will try to refresh the cache entry. For the duration of the refresh many clients may access the database server concurrently. In the worst case, the database server becomes overloaded and it takes more and more time to refresh the cache entry, which in turn lets more and more clients try to refresh the cache entry. To prevent this from happening the plugin has a slam defense mechanism. If slam defense is enabled and the plugin detects an expired cache entry it extends the life time of the cache entry before it refreshes the cache entry. This way other concurrent accesses to the expired cache entry are still served from the cache for a certain time. The other concurrent accesses to not trigger a concurrent refresh. Ideally, the cache entry gets refreshed by the client which extended the cache entries lifespan before other clients try to refresh the cache and potentially cause an overload situation.

Unique approach to caching

PECL/mysqlnd_qc has a unique approach to caching result sets that is superior to application based cache solutions. Application based solutions first fetch a result set into PHP variables. Then, the PHP variables are serialized for storage in a persistent cache, and then unserialized when fetching. The mysqlnd query cache stores the raw wire protocol data sent from MySQL to PHP in its cache and replays it, if still valid, on a cache hit. This way, it saves an extra serialization step for a cache put that all application based solutions have to do. It can store the raw wire protocol data in the cache without having to serialize into a PHP variable first and deserializing the PHP variable for storing in the cache again.

Setup

The plugin is implemented as a PHP extension. See also the installation instructions to install the » PECL/mysqlnd_qc extension.

Compile or configure the PHP MySQL extension (mysqli, PDO_MYSQL, mysql) that you plan to use with support for the mysqlnd library. PECL/mysqlnd_qc is a plugin for the mysqlnd library. To use the plugin with any of the existing PHP MySQL extensions (APIs), the extension has to use the mysqlnd library.

Then, load the extension into PHP and activate the plugin in the PHP configuration file using the PHP configuration directive named mysqlnd_qc.enable_qc.

示例 #1 Enabling the plugin (php.ini)

mysqlnd_qc.enable_qc=1

Caching queries

There are four ways to trigger caching of a query.

  • Use of SQL hints on a per query basis
  • User supplied callbacks to decide on a per query basis, for example, using <span class="function">mysqlnd_qc_is_select
  • <span class="function">mysqlnd_set_cache_condition for rule based automatic per query decisions
  • mysqlnd_qc.cache_by_default = 1 to cache all queries blindly

Use of SQL hints and mysqlnd_qc.cache_by_default = 1 are explained below. Please, refer to the function reference on <span class="function">mysqlnd_qc_is_select for a description of using a callback and, <span class="function">mysqlnd_qc_set_cache_condition on how to set rules for automatic caching.

A SQL hint is a SQL standards compliant comment. As a SQL comment it is ignored by the database. A statement is considered eligible for caching if it either begins with the SQL hint enabling caching or it is a SELECT statement.

An individual query which shall be cached must begin with the SQL hint /*qc=on*/. It is recommended to use the PHP constant MYSQLND_QC_ENABLE_SWITCH instead of using the string value.

  • not eligible for caching and not cached: INSERT INTO test(id) VALUES (1)

  • not eligible for caching and not cached: SHOW ENGINES

  • eligible for caching but uncached: SELECT id FROM test

  • eligible for caching and cached: /*qc=on*/SELECT id FROM test

The examples SELECT statement string is prefixed with the MYSQLND_QC_ENABLE_SWITCH SQL hint to enable caching of the statement. The SQL hint must be given at the very beginning of the statement string to enable caching.

示例 #1 Using the MYSQLND_QC_ENABLE_SWITCH SQL hint

mysqlnd_qc.enable_qc=1
<?php
/* Connect, create and populate test table */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1), (2)");

/* Will be cached because of the SQL hint */
$start = microtime(true);
$res   = $mysqli->query("/*" . MYSQLND_QC_ENABLE_SWITCH . "*/" . "SELECT id FROM test WHERE id = 1");

var_dump($res->fetch_assoc());
$res->free();

printf("Total time uncached query: %.6fs\n", microtime(true) - $start);

/* Cache hit */
$start = microtime(true);
$res   = $mysqli->query("/*" . MYSQLND_QC_ENABLE_SWITCH . "*/" . "SELECT id FROM test WHERE id = 1");

var_dump($res->fetch_assoc());
$res->free();

printf("Total time cached query: %.6fs\n", microtime(true) - $start);
?>

以上例程的输出类似于:

array(1) {
  ["id"]=>
  string(1) "1"
}
Total time uncached query: 0.000740s
array(1) {
  ["id"]=>
  string(1) "1"
}
Total time cached query: 0.000098s

If nothing else is configured, as it is the case in the quickstart example, the plugin will use the built-in default storage handler. The default storage handler uses process memory to hold a cache entry. Depending on the PHP deployment model, a PHP process may serve one or more web requests. Please, consult the web server manual for details. Details make no difference for the examples given in the quickstart.

The query cache plugin will cache all queries regardless if the query string begins with the SQL hint which enables caching or not, if the PHP configuration directive mysqlnd_qc.cache_by_default is set to 1. The setting mysqlnd_qc.cache_by_default is evaluated by the core of the query cache plugins. Neither the built-in nor user-defined storage handler can overrule the setting.

The SQL hint /*qc=off*/ can be used to disable caching of individual queries if mysqlnd_qc.cache_by_default = 1 It is recommended to use the PHP constant MYSQLND_QC_DISABLE_SWITCH instead of using the string value.

示例 #2 Using the MYSQLND_QC_DISABLE_SWITCH SQL hint

mysqlnd_qc.enable_qc=1
mysqlnd_qc.cache_by_default=1
<?php
/* Connect, create and populate test table */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1), (2)");

/* Will be cached although no SQL hint is present because of mysqlnd_qc.cache_by_default = 1*/
$res = $mysqli->query("SELECT id FROM test WHERE id = 1");
var_dump($res->fetch_assoc());
$res->free();

$mysqli->query("DELETE FROM test WHERE id = 1");

/* Cache hit - no automatic invalidation and still valid! */
$res = $mysqli->query("SELECT id FROM test WHERE id = 1");
var_dump($res->fetch_assoc());
$res->free();

/* Cache miss - query must not be cached because of the SQL hint */
$res = $mysqli->query("/*" . MYSQLND_QC_DISABLE_SWITCH . "*/SELECT id FROM test WHERE id = 1");
var_dump($res->fetch_assoc());
$res->free();
?>

以上例程会输出:

array(1) {
  ["id"]=>
  string(1) "1"
}
array(1) {
  ["id"]=>
  string(1) "1"
}
NULL

PECL/mysqlnd_qc forbids caching of statements for which at least one column from the statements result set shows no table name in its meta data by default. This is usually the case for columns originating from SQL functions such as NOW() or LAST_INSERT_ID(). The policy aims to prevent pitfalls if caching by default is used.

示例 #3 Example showing which type of statements are not cached

mysqlnd_qc.enable_qc=1
mysqlnd_qc.cache_by_default=1
<?php
/* Connect, create and populate test table */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1)");

for ($i = 0; $i < 3; $i++) {

    $start = microtime(true);

    /* Note: statement will not be cached because of NOW() use */
    $res = $mysqli->query("SELECT id, NOW() AS _time FROM test");
    $row = $res->fetch_assoc();

    /* dump results */
    var_dump($row);

    printf("Total time: %.6fs\n", microtime(true) - $start);

    /* pause one second */
    sleep(1);
}
?>

以上例程的输出类似于:

array(2) {
  ["id"]=>
  string(1) "1"
  ["_time"]=>
  string(19) "2012-01-11 15:43:10"
}
Total time: 0.000540s
array(2) {
  ["id"]=>
  string(1) "1"
  ["_time"]=>
  string(19) "2012-01-11 15:43:11"
}
Total time: 0.000555s
array(2) {
  ["id"]=>
  string(1) "1"
  ["_time"]=>
  string(19) "2012-01-11 15:43:12"
}
Total time: 0.000549s

It is possible to enable caching for all statements including those which has columns in their result set for which MySQL reports no table, such as the statement from the example. Set mysqlnd_qc.cache_no_table = 1 to enable caching of such statements. Please, note the difference in the measured times for the above and below examples.

示例 #4 Enabling caching for all statements using the mysqlnd_qc.cache_no_table ini setting

mysqlnd_qc.enable_qc=1
mysqlnd_qc.cache_by_default=1
mysqlnd_qc.cache_no_table=1
<?php
/* Connect, create and populate test table */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1)");

for ($i = 0; $i < 3; $i++) {

    $start = microtime(true);

    /* Note: statement will not be cached because of NOW() use */
    $res = $mysqli->query("SELECT id, NOW() AS _time FROM test");
    $row = $res->fetch_assoc();

    /* dump results */
    var_dump($row);

    printf("Total time: %.6fs\n", microtime(true) - $start);

    /* pause one second */
    sleep(1);
}
?>

以上例程的输出类似于:

array(2) {
  ["id"]=>
  string(1) "1"
  ["_time"]=>
  string(19) "2012-01-11 15:47:45"
}
Total time: 0.000546s
array(2) {
  ["id"]=>
  string(1) "1"
  ["_time"]=>
  string(19) "2012-01-11 15:47:45"
}
Total time: 0.000187s
array(2) {
  ["id"]=>
  string(1) "1"
  ["_time"]=>
  string(19) "2012-01-11 15:47:45"
}
Total time: 0.000167s

Note:

Although mysqlnd_qc.cache_no_table = 1 has been created for use with mysqlnd_qc.cache_by_default = 1 it is bound it. The plugin will evaluate the mysqlnd_qc.cache_no_table whenever a query is to be cached, no matter whether caching has been enabled using a SQL hint or any other measure.

Setting the TTL

The default invalidation strategy of the query cache plugin is Time to Live (TTL). The built-in storage handlers will use the default TTL defined by the PHP configuration value mysqlnd_qc.ttl unless the query string contains a hint for setting a different TTL. The TTL is specified in seconds. By default cache entries expire after 30 seconds

The example sets mysqlnd_qc.ttl=3 to cache statements for three seconds by default. Every second it updates a database table record to hold the current time and executes a SELECT statement to fetch the record from the database. The SELECT statement is cached for three seconds because it is prefixed with the SQL hint enabling caching. The output verifies that the query results are taken from the cache for the duration of three seconds before they are refreshed.

示例 #1 Setting the TTL with the mysqlnd_qc.ttl ini setting

mysqlnd_qc.enable_qc=1
mysqlnd_qc.ttl=3
<?php
/* Connect, create and populate test table */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id VARCHAR(255))");

for ($i = 0; $i < 7; $i++) {

    /* update DB row  */
    if (!$mysqli->query("DELETE FROM test") ||
        !$mysqli->query("INSERT INTO test(id) VALUES (NOW())"))
      /* Of course, a real-life script should do better error handling */
      die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));

    /* select latest row but cache results */
    $query  = "/*" . MYSQLND_QC_ENABLE_SWITCH . "*/";
    $query .= "SELECT id AS _time FROM test";
    if (!($res = $mysqli->query($query)) ||
        !($row = $res->fetch_assoc()))
    {
      printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
    }
    $res->free();
    printf("Wall time %s - DB row time %s\n", date("H:i:s"), $row['_time']);

    /* pause one second */
    sleep(1);
}
?>

以上例程的输出类似于:

Wall time 14:55:59 - DB row time 2012-01-11 14:55:59
Wall time 14:56:00 - DB row time 2012-01-11 14:55:59
Wall time 14:56:01 - DB row time 2012-01-11 14:55:59
Wall time 14:56:02 - DB row time 2012-01-11 14:56:02
Wall time 14:56:03 - DB row time 2012-01-11 14:56:02
Wall time 14:56:04 - DB row time 2012-01-11 14:56:02
Wall time 14:56:05 - DB row time 2012-01-11 14:56:05

As can be seen from the example, any TTL based cache can serve stale data. Cache entries are not automatically invalidated, if underlying data changes. Applications using the default TTL invalidation strategy must be able to work correctly with stale data.

A user-defined cache storage handler can implement any invalidation strategy to work around this limitation.

The default TTL can be overruled using the SQL hint /*qc_tt=seconds*/. The SQL hint must be appear immediately after the SQL hint which enables caching. It is recommended to use the PHP constant MYSQLND_QC_TTL_SWITCH instead of using the string value.

示例 #2 Setting TTL with SQL hints

<?php
$start = microtime(true);

/* Connect, create and populate test table */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1), (2)");

printf("Default TTL\t: %d seconds\n", ini_get("mysqlnd_qc.ttl"));

/* Will be cached for 2 seconds */
$sql = sprintf("/*%s*//*%s%d*/SELECT id FROM test WHERE id = 1", MYSQLND_QC_ENABLE_SWITCH, MYSQLND_QC_TTL_SWITCH, 2);
$res = $mysqli->query($sql);

var_dump($res->fetch_assoc());
$res->free();

$mysqli->query("DELETE FROM test WHERE id = 1");
sleep(1);

/* Cache hit - no automatic invalidation and still valid! */
$res = $mysqli->query($sql);
var_dump($res->fetch_assoc());
$res->free();

sleep(2);

/* Cache miss - cache entry has expired */
$res = $mysqli->query($sql);
var_dump($res->fetch_assoc());
$res->free();

printf("Script runtime\t: %d seconds\n", microtime(true) - $start);
?>

以上例程的输出类似于:

Default TTL     : 30 seconds
array(1) {
  ["id"]=>
  string(1) "1"
}
array(1) {
  ["id"]=>
  string(1) "1"
}
NULL
Script runtime  : 3 seconds

Pattern based caching

An application has three options for telling PECL/mysqlnd_qc whether a particular statement shall be used. The most basic approach is to cache all statements by setting mysqlnd_qc.cache_by_default = 1. This approach is often of little practical value. But it enables users to make a quick estimation about the maximum performance gains from caching. An application designed to use a cache may be able to prefix selected statements with the appropriate SQL hints. However, altering an applications source code may not always be possible or desired, for example, to avoid problems with software updates. Therefore, PECL/mysqlnd_qc allows setting a callback which decides if a query is to be cached.

The callback is installed with the <span class="function">mysqlnd_qc_set_is_select function. The callback is given the statement string of every statement inspected by the plugin. Then, the callback can decide whether to cache the function. The callback is supposed to return false if the statement shall not be cached. A return value of true makes the plugin try to add the statement into the cache. The cache entry will be given the default TTL ( mysqlnd_qc.ttl). If the callback returns a numerical value it is used as the TTL instead of the global default.

示例 #1 Setting a callback with <span class="function">mysqlnd_qc_set_is_select

mysqlnd_qc.enable_qc=1
mysqlnd_qc.collect_statistics=1
<?php
/* callback which decides if query is cached */
function is_select($query) {
    static $patterns = array(
      /* true - use default from mysqlnd_qc.ttl */
      "@SELECT\s+.*\s+FROM\s+test@ismU" => true,
      /* 3 - use TTL = 3 seconds */
      "@SELECT\s+.*\s+FROM\s+news@ismU" => 3
    );

    /* check if query does match pattern */
    foreach ($patterns as $pattern => $ttl) {
        if (preg_match($pattern, $query)) {
            printf("is_select(%45s): cache\n", $query);
            return $ttl;
        }
    }
    printf("is_select(%45s): do not cache\n", $query);
    return false;
}
/* install callback */
mysqlnd_qc_set_is_select("is_select");

/* Connect, create and populate test table */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1), (2), (3)");

/* cache put */
$mysqli->query("SELECT id FROM test WHERE id = 1");
/* cache hit */
$mysqli->query("SELECT id FROM test WHERE id = 1");
/* cache put */
$mysqli->query("SELECT * FROM test");

$stats = mysqlnd_qc_get_core_stats();
printf("Cache put: %d\n", $stats['cache_put']);
printf("Cache hit: %d\n", $stats['cache_hit']);
?>

以上例程的输出类似于:

is_select(                    DROP TABLE IF EXISTS test): do not cache
is_select(                    CREATE TABLE test(id INT)): do not cache
is_select(    INSERT INTO test(id) VALUES (1), (2), (3)): do not cache
is_select(             SELECT id FROM test WHERE id = 1): cache
is_select(             SELECT id FROM test WHERE id = 1): cache
is_select(                           SELECT * FROM test): cache
Cache put: 2
Cache hit: 1

The examples callback tests if a statement string matches a pattern. If this is the case, it either returns true to cache the statement using the global default TTL or an alternative TTL.

To minimize application changes the callback can put into and registered in an auto prepend file.

Slam defense

A badly designed cache can do more harm than good. In the worst case a cache can increase database server load instead of minimizing it. An overload situation can occur if a highly shared cache entry expires (cache stampeding).

Cache entries are shared and reused to a different degree depending on the storage used. The default storage handler stores cache entries in process memory. Thus, a cache entry can be reused for the life-span of a process. Other PHP processes cannot access it. If Memcache is used, a cache entry can be shared among multiple PHP processes and even among multiple machines, depending on the set up being used.

If a highly shared cache entry stored, for example, in Memcache expires, many clients gets a cache miss. Many client requests can no longer be served from the cache but try to run the underlying query on the database server. Until the cache entry is refreshed, more and more clients contact the database server. In the worst case, a total lost of service is the result.

The overload can be avoided using a storage handler which limits the reuse of cache entries to few clients. Then, at the average, its likely that only a limited number of clients will try to refresh a cache entry concurrently.

Additionally, the built-in slam defense mechanism can and should be used. If slam defense is activated an expired cache entry is given an extended life time. The first client getting a cache miss for the expired cache entry tries to refresh the cache entry within the extended life time. All other clients requesting the cache entry are temporarily served from the cache although the original TTL of the cache entry has expired. The other clients will not experience a cache miss before the extended life time is over.

示例 #1 Enabling the slam defense mechanism

mysqlnd_qc.slam_defense=1
mysqlnd_qc.slam_defense_ttl=1

The slam defense mechanism is enabled with the PHP configuration directive mysqlnd_qc.slam_defense. The extended life time of a cache entry is set with mysqlnd_qc.slam_defense_ttl.

The function mysqlnd_qc_get_core_stats returns an array of statistics. The statistics slam_stale_refresh and slam_stale_hit are incremented if slam defense takes place.

It is not possible to give a one-fits-all recommendation on the slam defense configuration. Users are advised to monitor and test their setup and derive settings accordingly.

Finding cache candidates

A statement should be considered for caching if it is executed often and has a long run time. Cache candidates are found by creating a list of statements sorted by the product of the number of executions multiplied by the statements run time. The function <span class="function">mysqlnd_qc_get_query_trace_log returns a query log which help with the task.

Collecting a query trace is a slow operation. Thus, it is disabled by default. The PHP configuration directive mysqlnd_qc.collect_query_trace is used to enable it. The functions trace contains one entry for every query issued before the function is called.

示例 #1 Collecting a query trace

mysqlnd_qc.enable_qc=1
mysqlnd_qc.collect_query_trace=1
<?php
/* connect to MySQL */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");

/* dummy queries to fill the query trace */
for ($i = 0; $i < 2; $i++) {
    $res = $mysqli->query("SELECT 1 AS _one FROM DUAL");
    $res->free();
}

/* dump trace */
var_dump(mysqlnd_qc_get_query_trace_log());
?>

以上例程会输出:

array(2) {
  [0]=>
  array(8) {
    ["query"]=>
    string(26) "SELECT 1 AS _one FROM DUAL"
    ["origin"]=>
    string(102) "#0 qc.php(7): mysqli->query('SELECT 1 AS _on...')
#1 {main}"
    ["run_time"]=>
    int(0)
    ["store_time"]=>
    int(25)
    ["eligible_for_caching"]=>
    bool(false)
    ["no_table"]=>
    bool(false)
    ["was_added"]=>
    bool(false)
    ["was_already_in_cache"]=>
    bool(false)
  }
  [1]=>
  array(8) {
    ["query"]=>
    string(26) "SELECT 1 AS _one FROM DUAL"
    ["origin"]=>
    string(102) "#0 qc.php(7): mysqli->query('SELECT 1 AS _on...')
#1 {main}"
    ["run_time"]=>
    int(0)
    ["store_time"]=>
    int(8)
    ["eligible_for_caching"]=>
    bool(false)
    ["no_table"]=>
    bool(false)
    ["was_added"]=>
    bool(false)
    ["was_already_in_cache"]=>
    bool(false)
  }
}

Assorted information is given in the trace. Among them timings and the origin of the query call. The origin property holds a code backtrace to identify the source of the query. The depth of the backtrace can be limited with the PHP configuration directive mysqlnd_qc.query_trace_bt_depth. The default depth is 3.

示例 #2 Setting the backtrace depth with the mysqlnd_qc.query_trace_bt_depth ini setting

mysqlnd_qc.enable_qc=1
mysqlnd_qc.collect_query_trace=1
<?php
/* connect to MySQL */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1), (2), (3)");

/* dummy queries to fill the query trace */
for ($i = 0; $i < 3; $i++) {
    $res = $mysqli->query("SELECT id FROM test WHERE id = " . $mysqli->real_escape_string($i));
    $res->free();
}

$trace = mysqlnd_qc_get_query_trace_log();
$summary = array();
foreach ($trace as $entry) {
    if (!isset($summary[$entry['query']])) {
        $summary[$entry['query']] = array(
            "executions" => 1,
            "time"       => $entry['run_time'] + $entry['store_time'],
        );
    } else {
        $summary[$entry['query']]['executions']++;
        $summary[$entry['query']]['time'] += $entry['run_time'] + $entry['store_time'];
    }
}

foreach ($summary as $query => $details) {
    printf("%45s: %5dms (%dx)\n",
    $query, $details['time'], $details['executions']);
}
?>

以上例程的输出类似于:

                    DROP TABLE IF EXISTS test:     0ms (1x)
                    CREATE TABLE test(id INT):     0ms (1x)
    INSERT INTO test(id) VALUES (1), (2), (3):     0ms (1x)
             SELECT id FROM test WHERE id = 0:    25ms (1x)
             SELECT id FROM test WHERE id = 1:    10ms (1x)
             SELECT id FROM test WHERE id = 2:     9ms (1x)

Measuring cache efficiency

PECL/mysqlnd_qc offers three ways to measure the cache efficiency. The function <span class="function">mysqlnd_qc_get_normalized_query_trace_log returns statistics aggregated by the normalized query string, <span class="function">mysqlnd_qc_get_cache_info gives storage handler specific information which includes a list of all cached items, depending on the storage handler. Additionally, the core of PECL/mysqlnd_qc collects high-level summary statistics aggregated per PHP process. The high-level statistics are returned by <span class="function">mysqlnd_qc_get_core_stats.

The functions <span class="function">mysqlnd_qc_get_normalized_query_trace_log and mysqlnd_qc_get_core_stats will not collect data unless data collection has been enabled through their corresponding PHP configuration directives. Data collection is disabled by default for performance considerations. It is configurable with the mysqlnd_qc.time_statistics option, which determines if timing information should be collected. Collection of time statistics is enabled by default but only performed if data collection as such has been enabled. Recording time statistics causes extra system calls. In most cases, the benefit of the monitoring outweighs any potential performance penalty of the additional system calls.

示例 #1 Collecting statistics data with the mysqlnd_qc.time_statistics ini setting

mysqlnd_qc.enable_qc=1
mysqlnd_qc.collect_statistics=1
<?php
/* connect to MySQL */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1), (2), (3)");

/* dummy queries */
for ($i = 1; $i <= 4; $i++) {
    $query = sprintf("/*%s*/SELECT id FROM test WHERE id = %d", MYSQLND_QC_ENABLE_SWITCH, $i % 2);
    $res   = $mysqli->query($query);

    $res->free();
}

var_dump(mysqlnd_qc_get_core_stats());
?>

以上例程的输出类似于:

array(26) {
  ["cache_hit"]=>
  string(1) "2"
  ["cache_miss"]=>
  string(1) "2"
  ["cache_put"]=>
  string(1) "2"
  ["query_should_cache"]=>
  string(1) "4"
  ["query_should_not_cache"]=>
  string(1) "3"
  ["query_not_cached"]=>
  string(1) "3"
  ["query_could_cache"]=>
  string(1) "4"
  ["query_found_in_cache"]=>
  string(1) "2"
  ["query_uncached_other"]=>
  string(1) "0"
  ["query_uncached_no_table"]=>
  string(1) "0"
  ["query_uncached_no_result"]=>
  string(1) "0"
  ["query_uncached_use_result"]=>
  string(1) "0"
  ["query_aggr_run_time_cache_hit"]=>
  string(2) "28"
  ["query_aggr_run_time_cache_put"]=>
  string(3) "900"
  ["query_aggr_run_time_total"]=>
  string(3) "928"
  ["query_aggr_store_time_cache_hit"]=>
  string(2) "14"
  ["query_aggr_store_time_cache_put"]=>
  string(2) "40"
  ["query_aggr_store_time_total"]=>
  string(2) "54"
  ["receive_bytes_recorded"]=>
  string(3) "136"
  ["receive_bytes_replayed"]=>
  string(3) "136"
  ["send_bytes_recorded"]=>
  string(2) "84"
  ["send_bytes_replayed"]=>
  string(2) "84"
  ["slam_stale_refresh"]=>
  string(1) "0"
  ["slam_stale_hit"]=>
  string(1) "0"
  ["request_counter"]=>
  int(1)
  ["process_hash"]=>
  int(1929695233)
}

For a quick overview, call <span class="function">mysqlnd_qc_get_core_stats. It delivers cache usage, cache timing and traffic related statistics. Values are aggregated on a per process basis for all queries issued by any PHP MySQL API call.

Some storage handler, such as the default handler, can report cache entries, statistics related to the entries and meta data for the underlying query through the <span class="function">mysqlnd_qc_get_cache_info function. Please note, that the information returned depends on the storage handler. Values are aggregated on a per process basis.

示例 #2 Example <span class="function">mysqlnd_qc_get_cache_info usage

mysqlnd_qc.enable_qc=1
<?php
/* connect to MySQL */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1), (2), (3)");

/* dummy queries to fill the query trace */
for ($i = 1; $i <= 4; $i++) {
    $query = sprintf("/*%s*/SELECT id FROM test WHERE id = %d", MYSQLND_QC_ENABLE_SWITCH, $i % 2);
    $res   = $mysqli->query($query);

    $res->free();
}

var_dump(mysqlnd_qc_get_cache_info());
?>

以上例程的输出类似于:

array(4) {
  ["num_entries"]=>
  int(2)
  ["handler"]=>
  string(7) "default"
  ["handler_version"]=>
  string(5) "1.0.0"
  ["data"]=>
  array(2) {
    ["Localhost via UNIX socket
3306
root
test|/*qc=on*/SELECT id FROM test WHERE id = 1"]=>
    array(2) {
      ["statistics"]=>
      array(11) {
        ["rows"]=>
        int(1)
        ["stored_size"]=>
        int(71)
        ["cache_hits"]=>
        int(1)
        ["run_time"]=>
        int(391)
        ["store_time"]=>
        int(27)
        ["min_run_time"]=>
        int(16)
        ["max_run_time"]=>
        int(16)
        ["min_store_time"]=>
        int(8)
        ["max_store_time"]=>
        int(8)
        ["avg_run_time"]=>
        int(8)
        ["avg_store_time"]=>
        int(4)
      }
      ["metadata"]=>
      array(1) {
        [0]=>
        array(8) {
          ["name"]=>
          string(2) "id"
          ["orig_name"]=>
          string(2) "id"
          ["table"]=>
          string(4) "test"
          ["orig_table"]=>
          string(4) "test"
          ["db"]=>
          string(4) "test"
          ["max_length"]=>
          int(1)
          ["length"]=>
          int(11)
          ["type"]=>
          int(3)
        }
      }
    }
    ["Localhost via UNIX socket
3306
root
test|/*qc=on*/SELECT id FROM test WHERE id = 0"]=>
    array(2) {
      ["statistics"]=>
      array(11) {
        ["rows"]=>
        int(0)
        ["stored_size"]=>
        int(65)
        ["cache_hits"]=>
        int(1)
        ["run_time"]=>
        int(299)
        ["store_time"]=>
        int(13)
        ["min_run_time"]=>
        int(11)
        ["max_run_time"]=>
        int(11)
        ["min_store_time"]=>
        int(6)
        ["max_store_time"]=>
        int(6)
        ["avg_run_time"]=>
        int(5)
        ["avg_store_time"]=>
        int(3)
      }
      ["metadata"]=>
      array(1) {
        [0]=>
        array(8) {
          ["name"]=>
          string(2) "id"
          ["orig_name"]=>
          string(2) "id"
          ["table"]=>
          string(4) "test"
          ["orig_table"]=>
          string(4) "test"
          ["db"]=>
          string(4) "test"
          ["max_length"]=>
          int(0)
          ["length"]=>
          int(11)
          ["type"]=>
          int(3)
        }
      }
    }
  }
}

It is possible to further break down the granularity of statistics to the level of the normalized statement string. The normalized statement string is the statements string with all parameters replaced with question marks. For example, the two statements SELECT id FROM test WHERE id = 0 and SELECT id FROM test WHERE id = 1 are normalized into SELECT id FROM test WHERE id = ?. Their both statistics are aggregated into one entry for SELECT id FROM test WHERE id = ?.

示例 #3 Example <span class="function">mysqlnd_qc_get_normalized_query_trace_log usage

mysqlnd_qc.enable_qc=1
mysqlnd_qc.collect_normalized_query_trace=1
<?php
/* connect to MySQL */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1), (2), (3)");

/* dummy queries to fill the query trace */
for ($i = 1; $i <= 4; $i++) {
    $query = sprintf("/*%s*/SELECT id FROM test WHERE id = %d", MYSQLND_QC_ENABLE_SWITCH, $i % 2);
    $res   = $mysqli->query($query);

    $res->free();
}

var_dump(mysqlnd_qc_get_normalized_query_trace_log());
?>

以上例程的输出类似于:

array(4) {
  [0]=>
  array(9) {
    ["query"]=>
    string(25) "DROP TABLE IF EXISTS test"
    ["occurences"]=>
    int(0)
    ["eligible_for_caching"]=>
    bool(false)
    ["avg_run_time"]=>
    int(0)
    ["min_run_time"]=>
    int(0)
    ["max_run_time"]=>
    int(0)
    ["avg_store_time"]=>
    int(0)
    ["min_store_time"]=>
    int(0)
    ["max_store_time"]=>
    int(0)
  }
  [1]=>
  array(9) {
    ["query"]=>
    string(27) "CREATE TABLE test (id INT )"
    ["occurences"]=>
    int(0)
    ["eligible_for_caching"]=>
    bool(false)
    ["avg_run_time"]=>
    int(0)
    ["min_run_time"]=>
    int(0)
    ["max_run_time"]=>
    int(0)
    ["avg_store_time"]=>
    int(0)
    ["min_store_time"]=>
    int(0)
    ["max_store_time"]=>
    int(0)
  }
  [2]=>
  array(9) {
    ["query"]=>
    string(46) "INSERT INTO test (id ) VALUES (? ), (? ), (? )"
    ["occurences"]=>
    int(0)
    ["eligible_for_caching"]=>
    bool(false)
    ["avg_run_time"]=>
    int(0)
    ["min_run_time"]=>
    int(0)
    ["max_run_time"]=>
    int(0)
    ["avg_store_time"]=>
    int(0)
    ["min_store_time"]=>
    int(0)
    ["max_store_time"]=>
    int(0)
  }
  [3]=>
  array(9) {
    ["query"]=>
    string(31) "SELECT id FROM test WHERE id =?"
    ["occurences"]=>
    int(4)
    ["eligible_for_caching"]=>
    bool(true)
    ["avg_run_time"]=>
    int(179)
    ["min_run_time"]=>
    int(11)
    ["max_run_time"]=>
    int(393)
    ["avg_store_time"]=>
    int(12)
    ["min_store_time"]=>
    int(7)
    ["max_store_time"]=>
    int(25)
  }
}

The source distribution of PECL/mysqlnd_qc contains a directory web/ in which web based monitoring scripts can be found which give an example how to write a cache monitor. Please, follow the instructions given in the source.

Since PECL/mysqlnd_qc 1.1.0 it is possible to write statistics into a log file. Please, see mysqlnd_qc.collect_statistics_log_file.

Beyond TTL: user-defined storage

The query cache plugin supports the use of user-defined storage handler. User-defined storage handler can use arbitrarily complex invalidation algorithms and support arbitrary storage media.

All user-defined storage handlers have to provide a certain interface. The functions of the user-defined storage handler will be called by the core of the cache plugin. The necessary interface consists of seven public functions. Both procedural and object oriented user-defined storage handler must implement the same set of functions.

示例 #1 Using a user-defined storage handler

<?php
/* Enable default caching of all statements */
ini_set("mysqlnd_qc.cache_by_default", 1);

/* Procedural user defined storage handler functions */

$__cache = array();

function get_hash($host_info, $port, $user, $db, $query) {
    global $__cache;
    printf("\t%s(%d)\n", __FUNCTION__, func_num_args());

    return md5(sprintf("%s%s%s%s%s", $host_info, $port, $user, $db, $query));
}

function find_query_in_cache($key) {
    global $__cache;
    printf("\t%s(%d)\n", __FUNCTION__, func_num_args());

    if (isset($__cache[$key])) {
        $tmp = $__cache[$key];
        if ($tmp["valid_until"] < time()) {
            unset($__cache[$key]);
            $ret = NULL;
        } else {
            $ret = $__cache[$key]["data"];
        }
    } else {
        $ret = NULL;
    }

    return $ret;
}

function return_to_cache($key) {
    /*
     Called on cache hit after cached data has been processed,
     may be used for reference counting
    */
    printf("\t%s(%d)\n", __FUNCTION__, func_num_args());
}

function add_query_to_cache_if_not_exists($key, $data, $ttl, $run_time, $store_time, $row_count) {
    global $__cache;
    printf("\t%s(%d)\n", __FUNCTION__, func_num_args());

    $__cache[$key] = array(
        "data"               => $data,
        "row_count"          => $row_count,
        "valid_until"        => time() + $ttl,
        "hits"               => 0,
        "run_time"           => $run_time,
        "store_time"         => $store_time,
        "cached_run_times"   => array(),
        "cached_store_times" => array(),
    );

    return TRUE;
}

function query_is_select($query) {
    printf("\t%s('%s'): ", __FUNCTION__, $query);

    $ret = FALSE;
    if (stristr($query, "SELECT") !== FALSE) {
        /* cache for 5 seconds */
        $ret = 5;
    }

    printf("%s\n", (FALSE === $ret) ? "FALSE" : $ret);
    return $ret;
}

function update_query_run_time_stats($key, $run_time, $store_time) {
    global $__cache;
    printf("\t%s(%d)\n", __FUNCTION__, func_num_args());

    if (isset($__cache[$key])) {
        $__cache[$key]['hits']++;
        $__cache[$key]["cached_run_times"][] = $run_time;
        $__cache[$key]["cached_store_times"][] = $store_time;
    }
}

function get_stats($key = NULL) {
    global $__cache;
    printf("\t%s(%d)\n", __FUNCTION__, func_num_args());

    if ($key && isset($__cache[$key])) {
        $stats = $__cache[$key];
    } else {
        $stats = array();
        foreach ($__cache as $key => $details) {
            $stats[$key] = array(
               'hits'              => $details['hits'],
               'bytes'             => strlen($details['data']),
               'uncached_run_time' => $details['run_time'],
               'cached_run_time'   => (count($details['cached_run_times']))
                                      ? array_sum($details['cached_run_times']) / count($details['cached_run_times'])
                                      : 0,
            );
        }
    }

    return $stats;
}

function clear_cache() {
    global $__cache;
    printf("\t%s(%d)\n", __FUNCTION__, func_num_args());

    $__cache = array();
    return TRUE;
}

/* Install procedural user-defined storage handler */
if (!mysqlnd_qc_set_user_handlers("get_hash", "find_query_in_cache",
    "return_to_cache", "add_query_to_cache_if_not_exists",
    "query_is_select", "update_query_run_time_stats", "get_stats", "clear_cache")) {

        printf("Failed to install user-defined storage handler\n");
}


/* Connect, create and populate test table */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1), (2)");

printf("\nCache put/cache miss\n");

$res = $mysqli->query("SELECT id FROM test WHERE id = 1");
var_dump($res->fetch_assoc());
$res->free();

/* Delete record to verify we get our data from the cache */
$mysqli->query("DELETE FROM test WHERE id = 1");

printf("\nCache hit\n");

$res = $mysqli->query("SELECT id FROM test WHERE id = 1");
var_dump($res->fetch_assoc());
$res->free();

printf("\nDisplay cache statistics\n");
var_dump(mysqlnd_qc_get_cache_info());

printf("\nFlushing cache, cache put/cache miss");
var_dump(mysqlnd_qc_clear_cache());

$res = $mysqli->query("SELECT id FROM test WHERE id = 1");
var_dump($res->fetch_assoc());
$res->free();
?>

以上例程的输出类似于:

        query_is_select('DROP TABLE IF EXISTS test'): FALSE
        query_is_select('CREATE TABLE test(id INT)'): FALSE
        query_is_select('INSERT INTO test(id) VALUES (1), (2)'): FALSE

Cache put/cache miss
        query_is_select('SELECT id FROM test WHERE id = 1'): 5
        get_hash(5)
        find_query_in_cache(1)
        add_query_to_cache_if_not_exists(6)
array(1) {
  ["id"]=>
  string(1) "1"
}
        query_is_select('DELETE FROM test WHERE id = 1'): FALSE

Cache hit
        query_is_select('SELECT id FROM test WHERE id = 1'): 5
        get_hash(5)
        find_query_in_cache(1)
        return_to_cache(1)
        update_query_run_time_stats(3)
array(1) {
  ["id"]=>
  string(1) "1"
}

Display cache statistics
        get_stats(0)
array(4) {
  ["num_entries"]=>
  int(1)
  ["handler"]=>
  string(4) "user"
  ["handler_version"]=>
  string(5) "1.0.0"
  ["data"]=>
  array(1) {
    ["18683c177dc89bb352b29965d112fdaa"]=>
    array(4) {
      ["hits"]=>
      int(1)
      ["bytes"]=>
      int(71)
      ["uncached_run_time"]=>
      int(398)
      ["cached_run_time"]=>
      int(4)
    }
  }
}

Flushing cache, cache put/cache miss    clear_cache(0)
bool(true)
        query_is_select('SELECT id FROM test WHERE id = 1'): 5
        get_hash(5)
        find_query_in_cache(1)
        add_query_to_cache_if_not_exists(6)
NULL

安装/配置

目录

需求

PHP 5.3.3 or a newer version of PHP.

PECL/mysqlnd_qc is a mysqlnd plugin. It plugs into the mysqlnd library. To use you this plugin with a PHP MySQL extension, the extension (mysqli, mysql, or PDO_MYSQL) must enable the mysqlnd library.

For using MEMCACHE storage handler: Use libmemcache 0.38 or newer. PECL/mysqlnd_qc 1.2 has been tested with libmemcache 1.4.0.

For using sqlite storage handler: Use the sqlite3 extension that bundled with PHP.

安装

» PECL 扩展未与 PHP 捆绑。

安装此 PECL 扩展相关的信息可在手册中标题为 PECL 扩展的安装章节中找到。更多信息如新的发行版本、下载、源文件、 维护人员信息及变更日志等,都在此处: » https://pecl.php.net/package/mysqlnd_qc

PECL 扩展的 DLL 当前不可用。参见 在 Windows 上构建章节。

运行时配置

这些函数的行为受 php.ini 中的设置影响。

名字 默认 可修改范围 更新日志
mysqlnd_qc.enable_qc 1 PHP_INI_SYSTEM
mysqlnd_qc.ttl 30 PHP_INI_ALL
mysqlnd_qc.cache_by_default 0 PHP_INI_ALL
mysqlnd_qc.cache_no_table 0 PHP_INI_ALL
mysqlnd_qc.use_request_time 0 PHP_INI_ALL
mysqlnd_qc.time_statistics 1 PHP_INI_ALL
mysqlnd_qc.collect_statistics 0 PHP_INI_ALL
mysqlnd_qc.collect_statistics_log_file /tmp/mysqlnd_qc.stats PHP_INI_SYSTEM
mysqlnd_qc.collect_query_trace 0 PHP_INI_SYSTEM
mysqlnd_qc.query_trace_bt_depth 3 PHP_INI_SYSTEM
mysqlnd_qc.collect_normalized_query_trace 0 PHP_INI_SYSTEM
mysqlnd_qc.ignore_sql_comments 1 PHP_INI_ALL
mysqlnd_qc.slam_defense 0 PHP_INI_SYSTEM
mysqlnd_qc.slam_defense_ttl 30 PHP_INI_SYSTEM
mysqlnd_qc.std_data_copy 0 PHP_INI_SYSTEM
mysqlnd_qc.apc_prefix qc_ PHP_INI_ALL
mysqlnd_qc.memc_server 127.0.0.1 PHP_INI_ALL
mysqlnd_qc.memc_port 11211 PHP_INI_ALL
mysqlnd_qc.sqlite_data_file :memory: PHP_INI_ALL

这是配置指令的简短说明。

mysqlnd_qc.enable_qc int
Enables or disables the plugin. If disabled the extension will not plug into mysqlnd to proxy internal mysqlnd C API calls.

mysqlnd_qc.ttl int
Default Time-to-Live (TTL) for cache entries in seconds.

mysqlnd_qc.cache_by_default int
Cache all queries regardless if they begin with the SQL hint that enables caching of a query or not. Storage handler cannot overrule the setting. It is evaluated by the core of the plugin.

mysqlnd_qc.cache_no_table int
Whether to cache queries with no table name in any of columns meta data of their result set, for example, SELECT SLEEP(1), SELECT NOW(), SELECT SUBSTRING().

mysqlnd_qc.use_request_time int
Use PHP global request time to avoid gettimeofday() system calls? If using APC storage handler it should be set to the value of apc.use_request_time, if not warnings will be generated.

mysqlnd_qc.time_statistics int
Collect run time and store time statistics using gettimeofday() system call? Data will be collected only if you also set mysqlnd_qc.collect_statistics = 1,

mysqlnd_qc.collect_statistics int
Collect statistics for <span class="function">mysqlnd_qc_get_core_stats? Does not influence storage handler statistics! Handler statistics can be an integral part of the handler internal storage format. Therefore, collection of some handler statistics cannot be disabled.

mysqlnd_qc.collect_statistics-log-file int
If mysqlnd_qc.collect_statistics and mysqlnd_qc.collect_statistics_log_file are set, the plugin will dump statistics into the specified log file at every 10th web request during PHP request shutdown. The log file needs to be writable by the web server user.

Since 1.1.0.

mysqlnd_qc.collect_query_trace int
Collect query back traces?

mysqlnd_qc.query_trace_bt_depth int
Maximum depth/level of a query code backtrace.

mysqlnd_qc.ignore_sql_comments int
Whether to remove SQL comments from a query string before hashing it to generate a cache key. Disable if you do not want two statemts such as SELECT /*my_source_ip=123*/ id FROM test and SELECT /*my_source_ip=456*/ id FROM test to refer to the same cache entry.

Since 1.1.0.

mysqlnd_qc.slam_defense int
Activates handler based slam defense (cache stampeding protection) if available. Supported by Default and APC storage handler

mysqlnd_qc.slam_defense_ttl int
TTL for stale cache entries which are served while another client updates the entries. Supported by APC storage handler.

mysqlnd_qc.collect_normalized_query_trace int
Collect aggregated normalized query traces? The setting has no effect by default. You compile the extension using the define NORM_QUERY_TRACE_LOG to make use of the setting.

mysqlnd_qc.std_data_copy int
Default storage handler: copy cached wire data? EXPERIMENTAL – use default setting!

mysqlnd_qc.apc_prefix string
The APC storage handler stores data in the APC user cache. The setting sets a prefix to be used for cache entries.

mysqlnd_qc.memc_server string
MEMCACHE storage handler: memcache server host.

mysqlnd_qc.memc_port int
MEMCACHE storage handler: memcached server port.

mysqlnd_qc.sqlite_data_file string
sqlite storage handler: data file. Any setting but :memory: may be of little practical value.

预定义常量

下列常量由此扩展定义,且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

SQL hint related

示例 #1 Using SQL hint constants

The query cache is controlled by SQL hints. SQL hints are used to enable and disable caching. SQL hints can be used to set the TTL of a query.

The SQL hints recognized by the query cache can be manually changed at compile time. This makes it possible to use mysqlnd_qc in environments in which the default SQL hints are already taken and interpreted by other systems. Therefore it is recommended to use the SQL hint string constants instead of manually adding the default SQL hints to the query string.

<?php
/* Use constants for maximum portability */
$query = "/*" . MYSQLND_QC_ENABLE_SWITCH . "*/SELECT id FROM test";

/* Valid but less portable: default TTL */
$query = "/*qc=on*/SELECT id FROM test";

/* Valid but less portable: per statement TTL */
$query = "/*qc=on*//*qc_ttl=5*/SELECT id FROM test";

printf("MYSQLND_QC_ENABLE_SWITCH: %s\n", MYSQLND_QC_ENABLE_SWITCH);
printf("MYSQLND_QC_DISABLE_SWITCH: %s\n", MYSQLND_QC_DISABLE_SWITCH);
printf("MYSQLND_QC_TTL_SWITCH: %s\n", MYSQLND_QC_TTL_SWITCH);
?>

以上例程会输出:

MYSQLND_QC_ENABLE_SWITCH: qc=on
MYSQLND_QC_DISABLE_SWITCH: qc=off
MYSQLND_QC_TTL_SWITCH: qc_ttl=

MYSQLND_QC_ENABLE_SWITCH (string)
SQL hint used to enable caching of a query.

MYSQLND_QC_DISABLE_SWITCH (string)
SQL hint used to disable caching of a query if mysqlnd_qc.cache_by_default = 1.

MYSQLND_QC_TTL_SWITCH (string)
SQL hint used to set the TTL of a result set.

MYSQLND_QC_SERVER_ID_SWITCH (string)
This SQL hint should not be used in general. It is needed by PECL/mysqlnd_ms to group cache entries for one statement but originating from different physical connections. If the hint is used connection settings such as user, hostname and charset are not considered for generating a cache key of a query. Instead the given value and the query string are used as input to the hashing function that generates the key. <span class="simpara"> PECL/mysqlnd_ms may, if instructed, cache results from MySQL Replication slaves. Because it can hold many connections to the slave the cache key shall not be formed from the user, hostname or other settings that may vary for the various slave connections. Instead, PECL/mysqlnd_ms provides an identifier which refers to the group of slave connections that shall be enabled to share cache entries no matter which physical slave connection was to generate the cache entry. Use of this feature outside of PECL/mysqlnd_ms is not recommended.

mysqlnd_qc_set_cache_condition related

示例 #2 Example <span class="function">mysqlnd_qc_set_cache_condition usage

The function <span class="function">mysqlnd_qc_set_cache_condition allows setting conditions for automatic caching of statements which don't begin with the SQL hints necessary to manually enable caching.

<?php
/* Cache all accesses to tables with the name "new%" in schema/database "db_example" for 1 second */
if (!mysqlnd_qc_set_cache_condition(MYSQLND_QC_CONDITION_META_SCHEMA_PATTERN, "db_example.new%", 1)) {
  die("Failed to set cache condition!");
}

$mysqli = new mysqli("host", "user", "password", "db_example", "port");
/* cached although no SQL hint given  */
$mysqli->query("SELECT id, title FROM news");

$pdo_mysql = new PDO("mysql:host=host;dbname=db_example;port=port", "user", "password");
/* not cached: no SQL hint, no pattern match */
$pdo_mysql->query("SELECT id, title FROM latest_news");
/* cached: TTL 1 second, pattern match */
$pdo_mysql->query("SELECT id, title FROM news");
?>

MYSQLND_QC_CONDITION_META_SCHEMA_PATTERN (int)
Used as a parameter of <span class="function">mysqlnd_qc_set_cache_condition to set conditions for schema based automatic caching.

Other

The plugin version number can be obtained using either MYSQLND_QC_VERSION, which is the string representation of the numerical version number, or MYSQLND_QC_VERSION_ID, which is an integer such as 10000. Developers can calculate the version number as follows.

Version (part) Example
Major*10000 1*10000 = 10000
Minor*100 0*100 = 0
Patch 0 = 0
MYSQLND_QC_VERSION_ID 10000

MYSQLND_QC_VERSION (string)
Plugin version string, for example, “1.0.0-prototype”.

MYSQLND_QC_VERSION_ID (int)
Plugin version number, for example, 10000.

mysqlnd_qc_clear_cache

Flush all cache contents

说明

bool <span class="methodname">mysqlnd_qc_clear_cache ( <span class="methodparam">void )

Flush all cache contents.

Flushing the cache is a storage handler responsibility. All built-in storage handler but the memcache storage handler support flushing the cache. The memcache storage handler cannot flush its cache contents.

User-defined storage handler may or may not support the operation.

参数

此函数没有参数。

返回值

成功时返回 true, 或者在失败时返回 false

A return value of false indicates that flushing all cache contents has failed or the operation is not supported by the active storage handler. Applications must not expect that calling the function will always flush the cache.

mysqlnd_qc_get_available_handlers

Returns a list of available storage handler

说明

array <span class="methodname">mysqlnd_qc_get_available_handlers ( <span class="methodparam">void )

Which storage are available depends on the compile time configuration of the query cache plugin. The default storage handler is always available. All other storage handler must be enabled explicitly when building the extension.

参数

此函数没有参数。

返回值

Returns an array of available built-in storage handler. For each storage handler the version number and version string is given.

范例

示例 #1 <span class="function">mysqlnd_qc_get_available_handlers example

<?php
var_dump(mysqlnd_qc_get_available_handlers());
?>

以上例程会输出:

array(5) {
  ["default"]=>
  array(2) {
    ["version"]=>
    string(5) "1.0.0"
    ["version_number"]=>
    int(100000)
  }
  ["user"]=>
  array(2) {
    ["version"]=>
    string(5) "1.0.0"
    ["version_number"]=>
    int(100000)
  }
  ["APC"]=>
  array(2) {
    ["version"]=>
    string(5) "1.0.0"
    ["version_number"]=>
    int(100000)
  }
  ["MEMCACHE"]=>
  array(2) {
    ["version"]=>
    string(5) "1.0.0"
    ["version_number"]=>
    int(100000)
  }
  ["sqlite"]=>
  array(2) {
    ["version"]=>
    string(5) "1.0.0"
    ["version_number"]=>
    int(100000)
  }
}

参见

mysqlnd_qc_get_cache_info

Returns information on the current handler, the number of cache entries and cache entries, if available

说明

array <span class="methodname">mysqlnd_qc_get_cache_info ( <span class="methodparam">void )

参数

此函数没有参数。

返回值

Returns information on the current handler, the number of cache entries and cache entries, if available. If and what data will be returned for the cache entries is subject to the active storage handler. Storage handler are free to return any data. Storage handler are recommended to return at least the data provided by the default handler, if technically possible.

The scope of the information is the PHP process. Depending on the PHP deployment model a process may serve one or more web requests.

Values are aggregated for all cache activities on a per storage handler basis. It is not possible to tell how much queries originating from mysqli, PDO_MySQL or mysql.API calls have contributed to the aggregated data values. Use <span class="function">mysqlnd_qc_get_core_stats to get timing data aggregated for all storage handlers.

Array of cache information

handler string
The active storage handler.

All storage handler. Since 1.0.0.

handler_version string
The version of the active storage handler.

All storage handler. Since 1.0.0.

num_entries int
The number of cache entries. The value depends on the storage handler in use.

The default, APC and SQLite storage handler provide the actual number of cache entries.

The MEMCACHE storage handler always returns 0. MEMCACHE does not support counting the number of cache entries.

If a user defined handler is used, the number of entries of the data property is reported.

Since 1.0.0.

data array
The version of the active storage handler.

Additional storage handler dependent data on the cache entries. Storage handler are requested to provide similar and comparable information. A user defined storage handler is free to return any data.

Since 1.0.0.

The following information is provided by the default storage handler for the data property.

The data property holds a hash. The hash is indexed by the internal cache entry identifier of the storage handler. The cache entry identifier is human-readable and contains the query string leading to the cache entry. Please, see also the example below. The following data is given for every cache entry.

statistics array
Statistics of the cache entry.

Since 1.0.0.

Property Description Version
rows Number of rows of the cached result set. Since 1.0.0.
stored_size The size of the cached result set in bytes. This is the size of the payload. The value is not suited for calculating the total memory consumption of all cache entries including the administrative overhead of the cache entries. Since 1.0.0.
cache_hits How often the cached entry has been returned. Since 1.0.0.
run_time Run time of the statement to which the cache entry belongs. This is the run time of the uncached statement. It is the time between sending the statement to MySQL receiving a reply from MySQL. Run time saved by using the query cache plugin can be calculated like this: cache_hits * ((run_time - avg_run_time) + (store_time - avg_store_time)). Since 1.0.0.
store_time Store time of the statements result set to which the cache entry belongs. This is the time it took to fetch and store the results of the uncached statement. Since 1.0.0.
min_run_time Minimum run time of the cached statement. How long it took to find the statement in the cache. Since 1.0.0.
min_store_time Minimum store time of the cached statement. The time taken for fetching the cached result set from the storage medium and decoding Since 1.0.0.
avg_run_time Average run time of the cached statement. Since 1.0.0.
avg_store_time Average store time of the cached statement. Since 1.0.0.
max_run_time Average run time of the cached statement. Since 1.0.0.
max_store_time Average store time of the cached statement. Since 1.0.0.
valid_until Timestamp when the cache entry expires. Since 1.1.0.

metadata array
Metadata of the cache entry. This is the metadata provided by MySQL together with the result set of the statement in question. Different versions of the MySQL server may return different metadata. Unlike with some of the PHP MySQL extensions no attempt is made to hide MySQL server version dependencies and version details from the caller. Please, refer to the MySQL C API documentation that belongs to the MySQL server in use for further details.

The metadata list contains one entry for every column.

Since 1.0.0.

Property Description Version
name The field name. Depending on the MySQL version this may be the fields alias name. Since 1.0.0.
org_name The field name. Since 1.0.0.
table The table name. If an alias name was used for the table, this usually holds the alias name. Since 1.0.0.
org_table The table name. Since 1.0.0.
db The database/schema name. Since 1.0.0.
max_length The maximum width of the field. Details may vary by MySQL server version. Since 1.0.0.
length The width of the field. Details may vary by MySQL server version. Since 1.0.0.
type The data type of the field. Details may vary by the MySQL server in use. This is the MySQL C API type constants value. It is recommended to use type constants provided by the mysqli extension to test for its meaning. You should not test for certain type values by comparing with certain numbers. Since 1.0.0.

The APC storage handler returns the same information for the data property but no metadata. The metadata of a cache entry is set to NULL.

The MEMCACHE storage handler does not fill the data property. Statistics are not available on a per cache entry basis with the MEMCACHE storage handler.

A user defined storage handler is free to provide any data.

范例

示例 #1 mysqlnd_qc_get_cache_info example

The example shows the output from the built-in default storage handler. Other storage handler may report different data.

<?php
/* Populate the cache, e.g. using mysqli */
$mysqli = new mysqli("host", "user", "password", "schema");
$mysqli->query("/*" . MYSQLND_QC_ENABLE_SWITCH . "*/SELECT id FROM test");

/* Display cache information */
var_dump(mysqlnd_qc_get_cache_info());
?>

以上例程会输出:

array(4) {
 ["num_entries"]=>
 int(1)
 ["handler"]=>
 string(7) "default"
 ["handler_version"]=>
 string(5) "1.0.0"
 ["data"]=>
 array(1) {
   ["Localhost via UNIX socket 3306 user schema|/*qc=on*/SELECT id FROM test"]=>
   array(2) {
     ["statistics"]=>
     array(11) {
       ["rows"]=>
       int(6)
       ["stored_size"]=>
       int(101)
       ["cache_hits"]=>
       int(0)
       ["run_time"]=>
       int(471)
       ["store_time"]=>
       int(27)
       ["min_run_time"]=>
       int(0)
       ["max_run_time"]=>
       int(0)
       ["min_store_time"]=>
       int(0)
       ["max_store_time"]=>
       int(0)
       ["avg_run_time"]=>
       int(0)
       ["avg_store_time"]=>
       int(0)
     }
     ["metadata"]=>
     array(1) {
       [0]=>
       array(8) {
         ["name"]=>
         string(2) "id"
         ["orig_name"]=>
         string(2) "id"
         ["table"]=>
         string(4) "test"
         ["orig_table"]=>
         string(4) "test"
         ["db"]=>
         string(4) "schema"
         ["max_length"]=>
         int(1)
         ["length"]=>
         int(11)
         ["type"]=>
         int(3)
       }
     }
   }
 }
}

参见

  • mysqlnd_qc_get_core_stats

mysqlnd_qc_get_core_stats

Statistics collected by the core of the query cache

说明

array <span class="methodname">mysqlnd_qc_get_core_stats ( <span class="methodparam">void )

Returns an array of statistics collected by the core of the cache plugin. The same data fields will be reported for any storage handler because the data is collected by the core.

The PHP configuration setting mysqlnd_qc.collect_statistics controls the collection of statistics. The collection of statistics is disabled by default for performance reasons. Disabling the collection of statistics will also disable the collection of time related statistics.

The PHP configuration setting mysqlnd_qc.collect_time_statistics controls the collection of time related statistics.

The scope of the core statistics is the PHP process. Depending on your deployment model a PHP process may handle one or multiple requests.

Statistics are aggregated for all cache entries and all storage handler. It is not possible to tell how much queries originating from mysqli, PDO_MySQL or mysql API calls have contributed to the aggregated data values.

参数

此函数没有参数。

返回值

Array of core statistics

Statistic Description Version
cache_hit Statement is considered cacheable and cached data has been reused. Statement is considered cacheable and a cache miss happened but the statement got cached by someone else while we process it and thus we can fetch the result from the refreshed cache. Since 1.0.0.
cache_miss Statement is considered cacheable...
  • ... and has been added to the cache

  • ... but the PHP configuration directive setting of mysqlnd_qc.cache_no_table = 1 has prevented caching.

  • ... but an unbuffered result set is requested.

  • ... but a buffered result set was empty.

Since 1.0.0.
cache_put Statement is considered cacheable and has been added to the cache. Take care when calculating derived statistics. Storage handler with a storage life time beyond process scope may report cache_put = 0 together with cache_hit > 0, if another process has filled the cache. You may want to use num_entries from mysqlnd_qc_get_cache_info if the handler supports it ( default, APC). Since 1.0.0.
query_should_cache Statement is considered cacheable based on query string analysis. The statement may or may not be added to the cache. See also cache_put. Since 1.0.0.
query_should_not_cache Statement is considered not cacheable based on query string analysis. Since 1.0.0.
query_not_cached Statement is considered not cacheable or it is considered cachable but the storage handler has not returned a hash key for it. Since 1.0.0.
query_could_cache Statement is considered cacheable...
  • ... and statement has been run without errors

  • ... and meta data shows at least one column in the result set

The statement may or may not be in the cache already. It may or may not be added to the cache later on.
Since 1.0.0.
query_found_in_cache Statement is considered cacheable and we have found it in the cache but we have not replayed the cached data yet and we have not send the result set to the client yet. This is not considered a cache hit because the client might not fetch the result or the cached data may be faulty. Since 1.0.0.
query_uncached_other Statement is considered cacheable and it may or may not be in the cache already but either replaying cached data has failed, no result set is available or some other error has happened.
query_uncached_no_table Statement has not been cached because the result set has at least one column which has no table name in its meta data. An example of such a query is SELECT SLEEP(1). To cache those statements you have to change default value of the PHP configuration directive mysqlnd_qc.cache_no_table and set mysqlnd_qc.cache_no_table = 1. Often, it is not desired to cache such statements. Since 1.0.0.
query_uncached_use_result Statement would have been cached if a buffered result set had been used. The situation is also considered as a cache miss and cache_miss will be incremented as well. Since 1.0.0.
query_aggr_run_time_cache_hit Aggregated run time (ms) of all cached queries. Cached queries are those which have incremented cache_hit. Since 1.0.0.
query_aggr_run_time_cache_put Aggregated run time (ms) of all uncached queries that have been put into the cache. See also cache_put. Since 1.0.0.
query_aggr_run_time_total Aggregated run time (ms) of all uncached and cached queries that have been inspected and executed by the query cache. Since 1.0.0.
query_aggr_store_time_cache_hit Aggregated store time (ms) of all cached queries. Cached queries are those which have incremented cache_hit. Since 1.0.0.
query_aggr_store_time_cache_put Aggregated store time ( ms) of all uncached queries that have been put into the cache. See also cache_put. Since 1.0.0.
query_aggr_store_time_total Aggregated store time (ms) of all uncached and cached queries that have been inspected and executed by the query cache. Since 1.0.0.
receive_bytes_recorded Recorded incoming network traffic ( bytes) send from MySQL to PHP. The traffic may or may not have been added to the cache. The traffic is the total for all queries regardless if cached or not. Since 1.0.0.
receive_bytes_replayed Network traffic replayed during cache. This is the total amount of incoming traffic saved because of the usage of the query cache plugin. Since 1.0.0.
send_bytes_recorded Recorded outgoing network traffic ( bytes) send from MySQL to PHP. The traffic may or may not have been added to the cache. The traffic is the total for all queries regardless if cached or not. Since 1.0.0.
send_bytes_replayed Network traffic replayed during cache. This is the total amount of outgoing traffic saved because of the usage of the query cache plugin. Since 1.0.0.
slam_stale_refresh Number of cache misses which triggered serving stale data until the client causing the cache miss has refreshed the cache entry. Since 1.0.0.
slam_stale_hit Number of cache hits while a stale cache entry gets refreshed. Since 1.0.0.

范例

示例 #1 mysqlnd_qc_get_core_stats example

<?php
/* Enable collection of statistics - default: disabled */
ini_set("mysqlnd_qc.collect_statistics", 1);

/* Enable collection of all timing related statistics -
default: enabled but overruled by mysqlnd_qc.collect_statistics = 0 */
ini_set("mysqlnd_qc.collect_time_statistics", 1);

/* Populate the cache, e.g. using mysqli */
$mysqli = new mysqli('host', 'user', 'password', 'schema');

/* Cache miss and cache put */
$mysqli->query("/*qc=on*/SELECT id FROM test");
/* Cache hit */
$mysqli->query("/*qc=on*/SELECT id FROM test");

/* Display core statistics */
var_dump(mysqlnd_qc_get_core_stats());
?>

以上例程会输出:

array(26) {
  ["cache_hit"]=>
  string(1) "1"
  ["cache_miss"]=>
  string(1) "1"
  ["cache_put"]=>
  string(1) "1"
  ["query_should_cache"]=>
  string(1) "2"
  ["query_should_not_cache"]=>
  string(1) "0"
  ["query_not_cached"]=>
  string(1) "0"
  ["query_could_cache"]=>
  string(1) "2"
  ["query_found_in_cache"]=>
  string(1) "1"
  ["query_uncached_other"]=>
  string(1) "0"
  ["query_uncached_no_table"]=>
  string(1) "0"
  ["query_uncached_no_result"]=>
  string(1) "0"
  ["query_uncached_use_result"]=>
  string(1) "0"
  ["query_aggr_run_time_cache_hit"]=>
  string(1) "4"
  ["query_aggr_run_time_cache_put"]=>
  string(3) "395"
  ["query_aggr_run_time_total"]=>
  string(3) "399"
  ["query_aggr_store_time_cache_hit"]=>
  string(1) "2"
  ["query_aggr_store_time_cache_put"]=>
  string(1) "8"
  ["query_aggr_store_time_total"]=>
  string(2) "10"
  ["receive_bytes_recorded"]=>
  string(2) "65"
  ["receive_bytes_replayed"]=>
  string(2) "65"
  ["send_bytes_recorded"]=>
  string(2) "29"
  ["send_bytes_replayed"]=>
  string(2) "29"
  ["slam_stale_refresh"]=>
  string(1) "0"
  ["slam_stale_hit"]=>
  string(1) "0"
  ["request_counter"]=>
  int(1)
  ["process_hash"]=>
  int(3547549858)
}

参见

mysqlnd_qc_get_normalized_query_trace_log

Returns a normalized query trace log for each query inspected by the query cache

说明

array <span class="methodname">mysqlnd_qc_get_normalized_query_trace_log ( void )

Returns a normalized query trace log for each query inspected by the query cache. The collection of the trace log is disabled by default. To collect the trace log you have to set the PHP configuration directive mysqlnd_qc.collect_normalized_query_trace to 1

Entries in the trace log are grouped by the normalized query statement. The normalized query statement is the query statement with all statement parameter values being replaced with a question mark. For example, the two statements SELECT id FROM test WHERE id = 1 and SELECT id FROM test WHERE id = 2 are normalized as SELECT id FROM test WHERE id = ?. Whenever a statement is inspected by the query cache which matches the normalized statement pattern, its statistics are grouped by the normalized statement string.

参数

此函数没有参数。

返回值

An array of query log. Every list entry contains the normalized query stringand further detail information.

Key Description
query Normalized statement string.
occurences How many statements have matched the normalized statement string in addition to the one which has created the log entry. The value is zero if a statement has been normalized, its normalized representation has been added to the log but no further queries inspected by PECL/mysqlnd_qc have the same normalized statement string.
eligible_for_caching Whether the statement could be cached. An statement eligible for caching has not necessarily been cached. It not possible to tell for sure if or how many cached statement have contributed to the aggregated normalized statement log entry. However, comparing the minimum and average run time one can make an educated guess.
avg_run_time The average run time of all queries contributing to the query log entry. The run time is the time between sending the query statement to MySQL and receiving an answer from MySQL.
avg_store_time The average store time of all queries contributing to the query log entry. The store time is the time needed to fetch a statements result set from the server to the client and, storing it on the client.
min_run_time The minimum run time of all queries contributing to the query log entry.
min_store_time The minimum store time of all queries contributing to the query log entry.
max_run_time The maximum run time of all queries contributing to the query log entry.
max_store_time The maximum store time of all queries contributing to the query log entry.

范例

示例 #1 <span class="function">mysqlnd_qc_get_normalized_query_trace_log example

mysqlnd_qc.collect_normalized_query_trace=1
<?php
/* Connect, create and populate test table */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1), (2)");

/* not cached */
$res = $mysqli->query("SELECT id FROM test WHERE id = 1");
var_dump($res->fetch_assoc());
$res->free();

/* cache put */
$res = $mysqli->query("/*" . MYSQLND_QC_ENABLE_SWITCH . "*/" . "SELECT id FROM test WHERE id = 2");
var_dump($res->fetch_assoc());
$res->free();

/* cache hit */
$res = $mysqli->query("/*" . MYSQLND_QC_ENABLE_SWITCH . "*/" . "SELECT id FROM test WHERE id = 2");
var_dump($res->fetch_assoc());
$res->free();

var_dump(mysqlnd_qc_get_normalized_query_trace_log());
?>

以上例程会输出:

array(1) {
  ["id"]=>
  string(1) "1"
}
array(1) {
  ["id"]=>
  string(1) "2"
}
array(1) {
  ["id"]=>
  string(1) "2"
}
array(4) {
  [0]=>
  array(9) {
    ["query"]=>
    string(25) "DROP TABLE IF EXISTS test"
    ["occurences"]=>
    int(0)
    ["eligible_for_caching"]=>
    bool(false)
    ["avg_run_time"]=>
    int(0)
    ["min_run_time"]=>
    int(0)
    ["max_run_time"]=>
    int(0)
    ["avg_store_time"]=>
    int(0)
    ["min_store_time"]=>
    int(0)
    ["max_store_time"]=>
    int(0)
  }
  [1]=>
  array(9) {
    ["query"]=>
    string(27) "CREATE TABLE test (id INT )"
    ["occurences"]=>
    int(0)
    ["eligible_for_caching"]=>
    bool(false)
    ["avg_run_time"]=>
    int(0)
    ["min_run_time"]=>
    int(0)
    ["max_run_time"]=>
    int(0)
    ["avg_store_time"]=>
    int(0)
    ["min_store_time"]=>
    int(0)
    ["max_store_time"]=>
    int(0)
  }
  [2]=>
  array(9) {
    ["query"]=>
    string(40) "INSERT INTO test (id ) VALUES (? ), (? )"
    ["occurences"]=>
    int(0)
    ["eligible_for_caching"]=>
    bool(false)
    ["avg_run_time"]=>
    int(0)
    ["min_run_time"]=>
    int(0)
    ["max_run_time"]=>
    int(0)
    ["avg_store_time"]=>
    int(0)
    ["min_store_time"]=>
    int(0)
    ["max_store_time"]=>
    int(0)
  }
  [3]=>
  array(9) {
    ["query"]=>
    string(31) "SELECT id FROM test WHERE id =?"
    ["occurences"]=>
    int(2)
    ["eligible_for_caching"]=>
    bool(true)
    ["avg_run_time"]=>
    int(159)
    ["min_run_time"]=>
    int(12)
    ["max_run_time"]=>
    int(307)
    ["avg_store_time"]=>
    int(10)
    ["min_store_time"]=>
    int(8)
    ["max_store_time"]=>
    int(13)
  }
}

参见

mysqlnd_qc_get_query_trace_log

Returns a backtrace for each query inspected by the query cache

说明

array <span class="methodname">mysqlnd_qc_get_query_trace_log ( <span class="methodparam">void )

Returns a backtrace for each query inspected by the query cache. The collection of the backtrace is disabled by default. To collect the backtrace you have to set the PHP configuration directive mysqlnd_qc.collect_query_trace to 1

The maximum depth of the backtrace is limited to the depth set with the PHP configuration directive mysqlnd_qc.query_trace_bt_depth.

参数

此函数没有参数。

返回值

An array of query backtrace. Every list entry contains the query string, a backtrace and further detail information.

Key Description
query Query string.
origin Code backtrace.
run_time Query run time in milliseconds. The collection of all times and the necessary gettimeofday system calls can be disabled by setting the PHP configuration directive mysqlnd_qc.time_statistics to 0
store_time Query result set store time in milliseconds. The collection of all times and the necessary gettimeofday system calls can be disabled by setting the PHP configuration directive mysqlnd_qc.time_statistics to 0
eligible_for_caching true if query is cacheable otherwise false.
no_table true if the query has generated a result set and at least one column from the result set has no table name set in its metadata. This is usually the case with queries which one probably do not want to cache such as SELECT SLEEP(1). By default any such query will not be added to the cache. See also PHP configuration directive mysqlnd_qc.cache_no_table.
was_added true if the query result has been put into the cache, otherwise false.
was_already_in_cache true if the query result would have been added to the cache if it was not already in the cache (cache hit). Otherwise false.

范例

示例 #1 <span class="function">mysqlnd_qc_get_query_trace_log example

mysqlnd_qc.collect_query_trace=1
<?php
/* Connect, create and populate test table */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1), (2)");

/* not cached */
$res = $mysqli->query("SELECT id FROM test WHERE id = 1");
var_dump($res->fetch_assoc());
$res->free();

/* cache put */
$res = $mysqli->query("/*" . MYSQLND_QC_ENABLE_SWITCH . "*/" . "SELECT id FROM test WHERE id = 2");
var_dump($res->fetch_assoc());
$res->free();

/* cache hit */
$res = $mysqli->query("/*" . MYSQLND_QC_ENABLE_SWITCH . "*/" . "SELECT id FROM test WHERE id = 2");
var_dump($res->fetch_assoc());
$res->free();

var_dump(mysqlnd_qc_get_query_trace_log());
?>

以上例程会输出:

array(1) {
  ["id"]=>
  string(1) "1"
}
array(1) {
  ["id"]=>
  string(1) "2"
}
array(1) {
  ["id"]=>
  string(1) "2"
}
array(6) {
  [0]=>
  array(8) {
    ["query"]=>
    string(25) "DROP TABLE IF EXISTS test"
    ["origin"]=>
    string(102) "#0 qc.php(4): mysqli->query('DROP TABLE IF E...')
#1 {main}"
    ["run_time"]=>
    int(0)
    ["store_time"]=>
    int(0)
    ["eligible_for_caching"]=>
    bool(false)
    ["no_table"]=>
    bool(false)
    ["was_added"]=>
    bool(false)
    ["was_already_in_cache"]=>
    bool(false)
  }
  [1]=>
  array(8) {
    ["query"]=>
    string(25) "CREATE TABLE test(id INT)"
    ["origin"]=>
    string(102) "#0 qc.php(5): mysqli->query('CREATE TABLE te...')
#1 {main}"
    ["run_time"]=>
    int(0)
    ["store_time"]=>
    int(0)
    ["eligible_for_caching"]=>
    bool(false)
    ["no_table"]=>
    bool(false)
    ["was_added"]=>
    bool(false)
    ["was_already_in_cache"]=>
    bool(false)
  }
  [2]=>
  array(8) {
    ["query"]=>
    string(36) "INSERT INTO test(id) VALUES (1), (2)"
    ["origin"]=>
    string(102) "#0 qc.php(6): mysqli->query('INSERT INTO tes...')
#1 {main}"
    ["run_time"]=>
    int(0)
    ["store_time"]=>
    int(0)
    ["eligible_for_caching"]=>
    bool(false)
    ["no_table"]=>
    bool(false)
    ["was_added"]=>
    bool(false)
    ["was_already_in_cache"]=>
    bool(false)
  }
  [3]=>
  array(8) {
    ["query"]=>
    string(32) "SELECT id FROM test WHERE id = 1"
    ["origin"]=>
    string(102) "#0 qc.php(9): mysqli->query('SELECT id FROM ...')
#1 {main}"
    ["run_time"]=>
    int(0)
    ["store_time"]=>
    int(25)
    ["eligible_for_caching"]=>
    bool(false)
    ["no_table"]=>
    bool(false)
    ["was_added"]=>
    bool(false)
    ["was_already_in_cache"]=>
    bool(false)
  }
  [4]=>
  array(8) {
    ["query"]=>
    string(41) "/*qc=on*/SELECT id FROM test WHERE id = 2"
    ["origin"]=>
    string(103) "#0 qc.php(14): mysqli->query('/*qc=on*/SELECT...')
#1 {main}"
    ["run_time"]=>
    int(311)
    ["store_time"]=>
    int(13)
    ["eligible_for_caching"]=>
    bool(true)
    ["no_table"]=>
    bool(false)
    ["was_added"]=>
    bool(true)
    ["was_already_in_cache"]=>
    bool(false)
  }
  [5]=>
  array(8) {
    ["query"]=>
    string(41) "/*qc=on*/SELECT id FROM test WHERE id = 2"
    ["origin"]=>
    string(103) "#0 qc.php(19): mysqli->query('/*qc=on*/SELECT...')
#1 {main}"
    ["run_time"]=>
    int(13)
    ["store_time"]=>
    int(8)
    ["eligible_for_caching"]=>
    bool(true)
    ["no_table"]=>
    bool(false)
    ["was_added"]=>
    bool(false)
    ["was_already_in_cache"]=>
    bool(true)
  }
}

参见

mysqlnd_qc_set_cache_condition

Set conditions for automatic caching

说明

bool <span class="methodname">mysqlnd_qc_set_cache_condition ( <span class="methodparam"> int $condition_type , mixed $condition , <span class="type">mixed $condition_option )

Sets a condition for automatic caching of statements which do not contain the necessary SQL hints to enable caching of them.

参数

condition_type
Type of the condition. The only allowed value is MYSQLND_QC_CONDITION_META_SCHEMA_PATTERN.

condition
Parameter for the condition set with condition_type. Parameter type and structure depend on condition_type

If condition_type equals MYSQLND_QC_CONDITION_META_SCHEMA_PATTERN condition must be a string. The string sets a pattern. Statements are cached if table and database meta data entry of their result sets match the pattern. The pattern is checked for a match with the db and org_table meta data entries provided by the underlying MySQL client server library. Please, check the MySQL Reference manual for details about the two entries. The db and org_table values are concatenated with a dot (.) before matched against condition. Pattern matching supports the wildcards % and _. The wildcard % will match one or many arbitrary characters. _ will match one arbitrary character. The escape symbol is backslash.

condition_option
Option for condition. Type and structure depend on condition_type.

If condition_type equals MYSQLND_QC_CONDITION_META_SCHEMA_PATTERN condition_options is the TTL to be used.

范例

示例 #1 <span class="function">mysqlnd_qc_set_cache_condition example

<?php
/* Cache all accesses to tables with the name "new%" in schema/database "db_example" for 1 second */
if (!mysqlnd_qc_set_cache_condition(MYSQLND_QC_CONDITION_META_SCHEMA_PATTERN, "db_example.new%", 1)) {
  die("Failed to set cache condition!");
}

$mysqli = new mysqli("host", "user", "password", "db_example", "port");
/* cached although no SQL hint given  */
$mysqli->query("SELECT id, title FROM news");

$pdo_mysql = new PDO("mysql:host=host;dbname=db_example;port=port", "user", "password");
/* not cached: no SQL hint, no pattern match */
$pdo_mysql->query("SELECT id, title FROM latest_news");
/* cached: TTL 1 second, pattern match */
$pdo_mysql->query("SELECT id, title FROM news");
?>

返回值

Returns TRUE on success or FALSE on FAILURE.

参见

mysqlnd_qc_set_is_select

Installs a callback which decides whether a statement is cached

说明

mixed <span class="methodname">mysqlnd_qc_set_is_select ( <span class="methodparam"> string $callback )

Installs a callback which decides whether a statement is cached.

There are several ways of hinting PELC/mysqlnd_qc to cache a query. By default, PECL/mysqlnd_qc attempts to cache a if caching of all statements is enabled or the query string begins with a certain SQL hint. The plugin internally calls a function named is_select() to find out. This internal function can be replaced with a user-defined callback. Then, the user-defined callback is responsible to decide whether the plugin attempts to cache a statement. Because the internal function is replaced with the callback, the callback gains full control. The callback is free to ignore the configuration setting mysqlnd_qc.cache_by_default and SQL hints.

The callback is invoked for every statement inspected by the plugin. It is given the statements string as a parameter. The callback returns false if the statement shall not be cached. It returns true to make the plugin attempt to cache the statements result set, if any. A so-created cache entry is given the default TTL set with the PHP configuration directive mysqlnd_qc.ttl. If a different TTL shall be used, the callback returns a numeric value to be used as the TTL.

The internal is_select function is part of the internal cache storage handler interface. Thus, a user-defined storage handler offers the same capabilities.

参数

此函数没有参数。

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 mysqlnd_qc_set_is_select example

<?php
/* callback which decides if query is cached */
function is_select($query) {
  static $patterns = array(
   /* true - use default from mysqlnd_qc.ttl */
   "@SELECT\s+.*\s+FROM\s+test@ismU" => true,
   /* 3 - use TTL = 3 seconds */
   "@SELECT\s+.*\s+FROM\s+news@ismU" => 3
  );
  /* check if query does match pattern */
  foreach ($patterns as $pattern => $ttl) {
    if (preg_match($pattern, $query)) {
      printf("is_select(%45s): cache\n", $query);
      return $ttl;
    }
  }
  printf("is_select(%45s): do not cache\n", $query);
  return false;
}
mysqlnd_qc_set_is_select("is_select");

/* Connect, create and populate test table */
$mysqli = new mysqli("host", "user", "password", "schema");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1), (2), (3)");

/* cache put */
$mysqli->query("SELECT id FROM test WHERE id = 1");
/* cache hit */
$mysqli->query("SELECT id FROM test WHERE id = 1");
/* cache put */
$mysqli->query("SELECT * FROM test");
?>

以上例程会输出:

is_select(                    DROP TABLE IF EXISTS test): do not cache
is_select(                    CREATE TABLE test(id INT)): do not cache
is_select(    INSERT INTO test(id) VALUES (1), (2), (3)): do not cache
is_select(             SELECT id FROM test WHERE id = 1): cache
is_select(             SELECT id FROM test WHERE id = 1): cache
is_select(                           SELECT * FROM test): cache

参见

mysqlnd_qc_set_storage_handler

Change current storage handler

说明

bool <span class="methodname">mysqlnd_qc_set_storage_handler ( <span class="methodparam"> string $handler )

Sets the storage handler used by the query cache. A list of available storage handler can be obtained from <span class="function">mysqlnd_qc_get_available_handlers. Which storage are available depends on the compile time configuration of the query cache plugin. The default storage handler is always available. All other storage handler must be enabled explicitly when building the extension.

参数

handler
Handler can be of type string representing the name of a built-in storage handler or an object of type mysqlnd_qc_handler_default. The names of the built-in storage handler are default, APC, MEMCACHE, sqlite.

返回值

成功时返回 true, 或者在失败时返回 false

If changing the storage handler fails a catchable fatal error will be thrown. The query cache cannot operate if the previous storage handler has been shutdown but no new storage handler has been installed.

范例

示例 #1 <span class="function">mysqlnd_qc_set_storage_handler example

The example shows the output from the built-in default storage handler. Other storage handler may report different data.

<?php
var_dump(mysqlnd_qc_set_storage_handler("memcache"));

if (true === mysqlnd_qc_set_storage_handler("default"))
  printf("Default storage handler activated");

/* Catchable fatal error */
var_dump(mysqlnd_qc_set_storage_handler("unknown"));
?>

以上例程会输出:

bool(true)
Default storage handler activated
Catchable fatal error: mysqlnd_qc_set_storage_handler(): Unknown handler 'unknown' in (file) on line (line)

参见

mysqlnd_qc_set_user_handlers

Sets the callback functions for a user-defined procedural storage handler

说明

bool <span class="methodname">mysqlnd_qc_set_user_handlers ( <span class="methodparam"> string $get_hash , string $find_query_in_cache , <span class="type">string $return_to_cache , <span class="methodparam"> string $add_query_to_cache_if_not_exists , string $query_is_select , <span class="methodparam"> string $update_query_run_time_stats , string $get_stats , <span class="methodparam"> string $clear_cache )

Sets the callback functions for a user-defined procedural storage handler.

参数

get_hash
Name of the user function implementing the storage handler get_hash functionality.

find_query_in_cache
Name of the user function implementing the storage handler find_in_cache functionality.

return_to_cache
Name of the user function implementing the storage handler return_to_cache functionality.

add_query_to_cache_if_not_exists
Name of the user function implementing the storage handler add_query_to_cache_if_not_exists functionality.

query_is_select
Name of the user function implementing the storage handler query_is_select functionality.

update_query_run_time_stats
Name of the user function implementing the storage handler update_query_run_time_stats functionality.

get_stats
Name of the user function implementing the storage handler get_stats functionality.

clear_cache
Name of the user function implementing the storage handler clear_cache functionality.

返回值

Returns TRUE on success or FALSE on FAILURE.

参见

目录

Change History

目录

This change history is a high level summary of selected changes that may impact applications and/or break backwards compatibility.

See also the CHANGES file in the source distribution for a complete list of changes.

PECL/mysqlnd_qc 1.2 series

1.2.0 - alpha

  • Release date: 03/2013
  • Motto/theme: PHP 5.5 compatibility

Feature changes

PECL/mysqlnd_qc 1.1 series

1.1.0 - stable

  • Release date: 04/2012
  • Motto/theme: PHP 5.4 compatibility, schema pattern based caching and mysqlnd_ms support

1.1.0 - beta

  • Release date: 04/2012
  • Motto/theme: PHP 5.4 compatibility, schema pattern based caching and mysqlnd_ms support

1.1.0 - alpha

  • Release date: 04/2012
  • Motto/theme: PHP 5.4 compatibility, schema pattern based caching and mysqlnd_ms support

Feature changes

  • APC storage handler update

    • Fix build for APC 3.1.9+
    • Note: Use of the APC storage handler is currently not recommended due to stability issues of APC itself.
  • New PHP configuration directives

  • New constants and SQL hints

  • New function <span class="function">mysqlnd_qc_set_cache_condition for built-in schema pattern based caching. Likely to support a wider range of conditions in the future.

  • Report valid_until timestamp for cache entries of the default handler through <span class="function">mysqlnd_qc_get_cache_info.

  • Include charset number for cache entry hashing. This should prevent serving result sets which have the wrong charset.

    API change: get_hash_key expects new "charsetnr" (int) parameter after "port".

  • API change: changing is_select() signature from bool is_select() to mixed is_select(). Mixed can be either boolean or array(long ttl, string server_id). This is needed by PECL/mysqlnd_ms.

Other

  • Support acting as a cache backend for PECL/mysqlnd_ms 1.3.0-beta or later to transparently replace MySQL Replication slave reads with cache accesses, if the user explicitly allows.

Bug fixes

  • Fixed Bug #59959 (config.m4, wrong library - 64bit memcached handler builds) (Credits: Remi Collet)

PECL/mysqlnd_qc 1.0 series

1.0.1-stable

  • Release date: 12/2010
  • Motto/theme: Prepared statement support

Added support for Prepared statements and unbuffered queries.

1.0.0-beta

  • Release date: 07/2010
  • Motto/theme: TTL-based cache with various storage options (Memcache, APC, SQLite, user-defined)

Initial public release of the transparent TTL-based query result cache. Flexible storage of cached results. Various storage media supported.

Mysqlnd user handler plugin

目录

The mysqlnd user handler plugin (mysqlnd_uh) allows users to set hooks for most internal calls of the MySQL native driver for PHP (mysqlnd). Mysqlnd and its plugins, including PECL/mysqlnd_uh, operate on a layer beneath the PHP MySQL extensions. A mysqlnd plugin can be considered as a proxy between the PHP MySQL extensions and the MySQL server as part of the PHP executable on the client-side. Because the plugins operates on their own layer below the PHP MySQL extensions, they can monitor and change application actions without requiring application changes. If the PHP MySQL extensions (mysqli, mysql, PDO_MYSQL) are compiled to use mysqlnd this can be used for:

  • Monitoring

    • Queries executed by any of the PHP MySQL extensions

    • Prepared statements executing by any of the PHP MySQL extensions

  • Auditing

    • Detection of database usage

    • SQL injection protection using black and white lists

  • Assorted

    • Load Balancing connections

The MySQL native driver for PHP (mysqlnd) features an internal plugin C API. C plugins, such as the mysqlnd user handler plugin, can extend the functionality of mysqlnd. PECL/mysqlnd_uh makes parts of the internal plugin C API available to the PHP user for plugin development with PHP.

Note: Status

The mysqlnd user handler plugin is in alpha status. Take appropriate care before using it in production environments.

Security considerations

PECL/mysqlnd_uh gives users access to MySQL user names, MySQL password used by any of the PHP MySQL extensions to connect to MySQL. It allows monitoring of all queries and prepared statements exposing the statement string to the user. Therefore, the extension should be installed with care. The PHP_INI_SYSTEM configuration setting mysqlnd_uh.enable can be used to prevent users from hooking mysqlnd calls.

Code obfuscators and similar technologies are not suitable to prevent monitoring of mysqlnd library activities if PECL/mysqlnd_uh is made available and the user can install a proxy, for example, using auto_prepend_file.

Documentation note

Many of the mysqlnd_uh functions are briefly described because the mysqli extension is a thin abstraction layer on top of the MySQL C API that the mysqlnd library provides. Therefore, the corresponding mysqli documentation (along with the MySQL reference manual) can be consulted to receive more information about a particular function.

On the name

The shortcut mysqlnd_uh stands for mysqlnd user handler, and has been the name since early development.

Quickstart and Examples

目录

The mysqlnd user handler plugin can be understood as a client-side proxy for all PHP MySQL extensions (mysqli, mysql, PDO_MYSQL), if they are compiled to use the mysqlnd library. The extensions use the mysqlnd library internally, at the C level, to communicate with the MySQL server. PECL/mysqlnd_uh allows it to hook many mysqlnd calls. Therefore, most activities of the PHP MySQL extensions can be monitored.

Because monitoring happens at the level of the library, at a layer below the application, it is possible to monitor applications without changing them.

On the C level, the mysqlnd library is structured in modules or classes. The extension hooks almost all methods of the mysqlnd internal connection class and exposes them through the user space class MysqlndUhConnection. Some few methods of the mysqlnd internal statement class are made available to the PHP user with the class <span class="classname">MysqlndUhPreparedStatement. By subclassing the classes MysqlndUhConnection and <span class="classname">MysqlndUhPreparedStatement users get access to mysqlnd internal function calls.

Note:

The internal mysqlnd function calls are not designed to be exposed to the PHP user. Manipulating their activities may cause PHP to crash or leak memory. Often, this is not considered a bug. Please, keep in mind that you are accessing C library functions through PHP which are expected to take certain actions, which you may not be able to emulate in user space. Therefore, it is strongly recommended to always call the parent method implementation when subclassing <span class="classname">MysqlndUhConnection or <span class="classname">MysqlndUhPreparedStatement. To prevent the worst case, the extension performs some sanity checks. Please, see also the Mysqlnd_uh 配置选项.

Setup

The plugin is implemented as a PHP extension. See the installation instructions to install the » PECL/mysqlnd_uh extension. Then, load the extension into PHP and activate the plugin in the PHP configuration file using the PHP configuration directive named mysqlnd_uh.enable. The below example shows the default settings of the extension.

示例 #1 Enabling the plugin (php.ini)

mysqlnd_uh.enable=1
mysqlnd_uh.report_wrong_types=1

How it works

This describes the background and inner workings of the mysqlnd_uh extension.

Two classes are provided by the extension: <span class="classname">MysqlndUhConnection and <span class="classname">MysqlndUhPreparedStatement. <span class="classname">MysqlndUhConnection lets you access almost all methods of the mysqlnd internal connection class. The latter exposes some selected methods of the mysqlnd internal statement class. For example, MysqlndUhConnection::connect maps to the mysqlnd library C function mysqlnd_conn__connect.

As a mysqlnd plugin, the PECL/mysqlnd_uh extension replaces mysqlnd library C functions with its own functions. Whenever a PHP MySQL extension compiled to use mysqlnd calls a mysqlnd function, the functions installed by the plugin are executed instead of the original mysqlnd ones. For example, <span class="function">mysqli_connect invokes mysqlnd_conn__connect, so the connect function installed by PECL/mysqlnd_uh will be called. The functions installed by PECL/mysqlnd_uh are the methods of the built-in classes.

The built-in PHP classes and their methods do nothing but call their mysqlnd C library counterparts, to behave exactly like the original mysqlnd function they replace. The code below illustrates in pseudo-code what the extension does.

示例 #1 Pseudo-code: what a built-in class does

class MysqlndUhConnection {
  public function connect(($conn, $host, $user, $passwd, $db, $port, $socket, $mysql_flags) {
    MYSQLND* c_mysqlnd_connection = convert_from_php_to_c($conn);
    ...
    return call_c_function(mysqlnd_conn__connect(c_mysqlnd_connection, ...));
  }
}

The build-in classes behave like a transparent proxy. It is possible for you to replace the proxy with your own. This is done by subclassing MysqlndUhConnection or <span class="classname">MysqlndUhPreparedStatement to extend the functionality of the proxy, followed by registering a new proxy object. Proxy objects are installed by <span class="function">mysqlnd_uh_set_connection_proxy and <span class="function">mysqlnd_uh_set_statement_proxy.

示例 #2 Installing a proxy

<?php
class proxy extends MysqlndUhConnection {
 public function connect($res, $host, $user, $passwd, $db, $port, $socket, $mysql_flags) {
   printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
   $ret = parent::connect($res, $host, $user, $passwd, $db, $port, $socket, $mysql_flags);
   printf("%s returns %s\n", __METHOD__, var_export($ret, true));
   return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
?>

以上例程会输出:

proxy::connect(array (
  0 => NULL,
  1 => 'localhost',
  2 => 'root',
  3 => '',
  4 => 'test',
  5 => 3306,
  6 => NULL,
  7 => 131072,
))
proxy::connect returns true

Installing a proxy

The extension provides two built-in classes: <span class="classname">MysqlndUhConnection and <span class="classname">MysqlndUhPreparedStatement. The classes are used for hooking mysqlnd library calls. Their methods correspond to mysqlnd internal functions. By default they act like a transparent proxy and do nothing but call their mysqlnd counterparts. By subclassing the classes you can install your own proxy to monitor mysqlnd.

See also the How it works guide to learn about the inner workings of this extension.

Connection proxies are objects of the type <span class="classname">MysqlndUhConnection. Connection proxy objects are installed by <span class="function">mysqlnd_uh_set_connection_proxy. If you install the built-in class <span class="classname">MysqlndUhConnection as a proxy, nothing happens. It behaves like a transparent proxy.

示例 #1 Proxy registration, mysqlnd_uh.enable=1

<?php
mysqlnd_uh_set_connection_proxy(new MysqlndUhConnection());
$mysqli = new mysqli("localhost", "root", "", "test");
?>

The PHP_INI_SYSTEM configuration setting mysqlnd_uh.enable controls whether a proxy may be set. If disabled, the extension will throw errors of type E_WARNING

示例 #2 Proxy installation disabled

mysqlnd_uh.enable=0
<?php
mysqlnd_uh_set_connection_proxy(new MysqlndUhConnection());
$mysqli = new mysqli("localhost", "root", "", "test");
?>

以上例程会输出:

PHP Warning:  MysqlndUhConnection::__construct(): (Mysqlnd User Handler) The plugin has been disabled by setting the configuration parameter mysqlnd_uh.enabled = false.  You must not use any of the base classes in %s on line %d
PHP Warning:  mysqlnd_uh_set_connection_proxy(): (Mysqlnd User Handler) The plugin has been disabled by setting the configuration parameter mysqlnd_uh.enable = false. The proxy has not been installed  in %s on line %d

To monitor mysqlnd, you have to write your own proxy object subclassing MysqlndUhConnection. Please, see the function reference for a the list of methods that can be subclassed. Alternatively, you can use reflection to inspect the built-in MysqlndUhConnection.

Create a new class proxy. Derive it from the built-in class <span class="classname">MysqlndUhConnection. Replace the <span class="function">MysqlndUhConnection::connect. method. Print out the host parameter value passed to the method. Make sure that you call the parent implementation of the connect method. Failing to do so may give unexpected and undesired results, including memory leaks and crashes.

Register your proxy and open three connections using the PHP MySQL extensions mysqli, mysql, PDO_MYSQL. If the extensions have been compiled to use the mysqlnd library, the proxy::connect method will be called three times, once for each connection opened.

示例 #3 Connection proxy

<?php
class proxy extends MysqlndUhConnection {
  public function connect($res, $host, $user, $passwd, $db, $port, $socket, $mysql_flags) {
   printf("Connection opened to '%s'\n", $host);
   /* Always call the parent implementation! */
   return parent::connect($res, $host, $user, $passwd, $db, $port, $socket, $mysql_flags);
  }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$mysql = mysql_connect("localhost", "root", "");
$pdo = new PDO("mysql:host=localhost;dbname=test", "root", "");
?>

以上例程会输出:

Connection opened to 'localhost'
Connection opened to 'localhost'
Connection opened to 'localhost'

The use of prepared statement proxies follows the same pattern: create a proxy object of the type <span class="classname">MysqlndUhPreparedStatement and install the proxy using <span class="function">mysqlnd_uh_set_statement_proxy.

示例 #4 Prepared statement proxy

<?php
class stmt_proxy extends MysqlndUhPreparedStatement {
 public function prepare($res, $query) {
  printf("%s(%s)\n", __METHOD__, $query);
  return parent::prepare($res, $query);
 }
}
mysqlnd_uh_set_statement_proxy(new stmt_proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$stmt = $mysqli->prepare("SELECT 'mysqlnd hacking made easy' AS _msg FROM DUAL");
?>

以上例程会输出:

stmt_proxy::prepare(SELECT 'mysqlnd hacking made easy' AS _msg FROM DUAL)

Basic query monitoring

Basic monitoring of a query statement is easy with PECL/mysqlnd_uh. Combined with debug_print_backtrace it can become a powerful tool, for example, to find the origin of certain statement. This may be desired when searching for slow queries but also after database refactoring to find code still accessing deprecated databases or tables. The latter may be a complicated matter to do otherwise, especially if the application uses auto-generated queries.

示例 #1 Basic Monitoring

<?php
class conn_proxy extends MysqlndUhConnection {
 public function query($res, $query) {
  debug_print_backtrace();
  return parent::query($res, $query);
 }
}
class stmt_proxy extends MysqlndUhPreparedStatement {
 public function prepare($res, $query) {
  debug_print_backtrace();
  return parent::prepare($res, $query);
 }
}
mysqlnd_uh_set_connection_proxy(new conn_proxy());
mysqlnd_uh_set_statement_proxy(new stmt_proxy());

printf("Proxies installed...\n");
$pdo = new PDO("mysql:host=localhost;dbname=test", "root", "");
var_dump($pdo->query("SELECT 1 AS _one FROM DUAL")->fetchAll(PDO::FETCH_ASSOC));

$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->prepare("SELECT 1 AS _two FROM DUAL");
?>

以上例程会输出:

#0  conn_proxy->query(Resource id #19, SELECT 1 AS _one FROM DUAL)
#1  PDO->query(SELECT 1 AS _one FROM DUAL) called at [example.php:19]
array(1) {
  [0]=>
  array(1) {
    ["_one"]=>
    string(1) "1"
  }
}
#0  stmt_proxy->prepare(Resource id #753, SELECT 1 AS _two FROM DUAL)
#1  mysqli->prepare(SELECT 1 AS _two FROM DUAL) called at [example.php:22]

For basic query monitoring you should install a connection and a prepared statement proxy. The connection proxy should subclass <span class="function">MysqlndUhConnection::query. All database queries not using native prepared statements will call this method. In the example the query function is invoked by a PDO call. By default, PDO_MySQL is using prepared statement emulation.

All native prepared statements are prepared with the prepare method of mysqlnd exported through <span class="methodname">MysqlndUhPreparedStatement::prepare. Subclass MysqlndUhPreparedStatement and overwrite prepare for native prepared statement monitoring.

安装/配置

目录

需求

PHP 5.3.3 or later. It is recommended to use PHP 5.4.0 or later to get access to the latest mysqlnd features.

The mysqlnd_uh user handler plugin supports all PHP applications and all available PHP MySQL extensions (mysqli, mysql, PDO_MYSQL). The PHP MySQL extension must be configured to use mysqlnd in order to be able to use the mysqlnd_uh plugin for mysqlnd.

The alpha versions makes use of some mysqli features. You must enable mysqli to compile the plugin. This requirement may be removed in the future. Note, that this requirement does not restrict you to use the plugin only with mysqli. You can use the plugin to monitor mysql, mysqli and PDO_MYSQL.

安装

安装此 PECL 扩展相关的信息可在手册中标题为 PECL 扩展的安装章节中找到。更多信息如新的发行版本、下载、源文件、 维护人员信息及变更日志等,都在此处: » https://pecl.php.net/package/mysqlnd-uh

PECL/mysqlnd_uh is currently not available on Windows. The source code of the extension makes use of C99 constructs not allowed with PHP Windows builds.

运行时配置

这些函数的行为受 php.ini 中的设置影响。

名字 默认 可修改范围 更新日志
mysqlnd_uh.enable 1 PHP_INI_SYSTEM
mysqlnd_uh.report_wrong_types 1 PHP_INI_ALL

这是配置指令的简短说明。

mysqlnd_uh.enable int
Enables or disables the plugin. If set to disabled, the extension will not allow users to plug into mysqlnd to hook mysqlnd calls.

mysqlnd_uh.report_wrong_types int
Whether to report wrong return value types of user hooks as E_WARNING level errors. This is recommended for detecting errors.

资源类型

此扩展没有定义资源类型。

预定义常量

下列常量由此扩展定义,且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

Most of the constants refer to details of the MySQL Client Server Protocol. Please, refer to the MySQL reference manual to learn about their meaning. To avoid content duplication, only short descriptions are given.

MysqlndUhConnection::simpleCommand related

The following constants can be used to detect what command is to be send through <span class="methodname">MysqlndUhConnection::simpleCommand.

MYSQLND_UH_MYSQLND_COM_SLEEP (int)
MySQL Client Server protocol command: COM_SLEEP.

MYSQLND_UH_MYSQLND_COM_QUIT (int)
MySQL Client Server protocol command: COM_QUIT.

MYSQLND_UH_MYSQLND_COM_INIT_DB (int)
MySQL Client Server protocol command: COM_INIT_DB.

MYSQLND_UH_MYSQLND_COM_QUERY (int)
MySQL Client Server protocol command: COM_QUERY.

MYSQLND_UH_MYSQLND_COM_FIELD_LIST (int)
MySQL Client Server protocol command: COM_FIELD_LIST.

MYSQLND_UH_MYSQLND_COM_CREATE_DB (int)
MySQL Client Server protocol command: COM_CREATE_DB.

MYSQLND_UH_MYSQLND_COM_DROP_DB (int)
MySQL Client Server protocol command: COM_DROP_DB.

MYSQLND_UH_MYSQLND_COM_REFRESH (int)
MySQL Client Server protocol command: COM_REFRESH.

MYSQLND_UH_MYSQLND_COM_SHUTDOWN (int)
MySQL Client Server protocol command: COM_SHUTDOWN.

MYSQLND_UH_MYSQLND_COM_STATISTICS (int)
MySQL Client Server protocol command: COM_STATISTICS.

MYSQLND_UH_MYSQLND_COM_PROCESS_INFO (int)
MySQL Client Server protocol command: COM_PROCESS_INFO.

MYSQLND_UH_MYSQLND_COM_CONNECT (int)
MySQL Client Server protocol command: COM_CONNECT.

MYSQLND_UH_MYSQLND_COM_PROCESS_KILL (int)
MySQL Client Server protocol command: COM_PROCESS_KILL.

MYSQLND_UH_MYSQLND_COM_DEBUG (int)
MySQL Client Server protocol command: COM_DEBUG.

MYSQLND_UH_MYSQLND_COM_PING (int)
MySQL Client Server protocol command: COM_PING.

MYSQLND_UH_MYSQLND_COM_TIME (int)
MySQL Client Server protocol command: COM_TIME.

MYSQLND_UH_MYSQLND_COM_DELAYED_INSERT (int)
MySQL Client Server protocol command: COM_DELAYED_INSERT.

MYSQLND_UH_MYSQLND_COM_CHANGE_USER (int)
MySQL Client Server protocol command: COM_CHANGE_USER.

MYSQLND_UH_MYSQLND_COM_BINLOG_DUMP (int)
MySQL Client Server protocol command: COM_BINLOG_DUMP.

MYSQLND_UH_MYSQLND_COM_TABLE_DUMP (int)
MySQL Client Server protocol command: COM_TABLE_DUMP.

MYSQLND_UH_MYSQLND_COM_CONNECT_OUT (int)
MySQL Client Server protocol command: COM_CONNECT_OUT.

MYSQLND_UH_MYSQLND_COM_REGISTER_SLAVED (int)
MySQL Client Server protocol command: COM_REGISTER_SLAVED.

MYSQLND_UH_MYSQLND_COM_STMT_PREPARE (int)
MySQL Client Server protocol command: COM_STMT_PREPARE.

MYSQLND_UH_MYSQLND_COM_STMT_EXECUTE (int)
MySQL Client Server protocol command: COM_STMT_EXECUTE.

MYSQLND_UH_MYSQLND_COM_STMT_SEND_LONG_DATA (int)
MySQL Client Server protocol command: COM_STMT_SEND_LONG_DATA.

MYSQLND_UH_MYSQLND_COM_STMT_CLOSE (int)
MySQL Client Server protocol command: COM_STMT_CLOSE.

MYSQLND_UH_MYSQLND_COM_STMT_RESET (int)
MySQL Client Server protocol command: COM_STMT_RESET.

MYSQLND_UH_MYSQLND_COM_SET_OPTION (int)
MySQL Client Server protocol command: COM_SET_OPTION.

MYSQLND_UH_MYSQLND_COM_STMT_FETCH (int)
MySQL Client Server protocol command: COM_STMT_FETCH.

MYSQLND_UH_MYSQLND_COM_DAEMON (int)
MySQL Client Server protocol command: COM_DAEMON.

MYSQLND_UH_MYSQLND_COM_END (int)
MySQL Client Server protocol command: COM_END.

The following constants can be used to analyze the ok_packet argument of MysqlndUhConnection::simpleCommand.

MYSQLND_UH_MYSQLND_PROT_GREET_PACKET (int)
MySQL Client Server protocol packet: greeting.

MYSQLND_UH_MYSQLND_PROT_AUTH_PACKET (int)
MySQL Client Server protocol packet: authentication.

MYSQLND_UH_MYSQLND_PROT_OK_PACKET (int)
MySQL Client Server protocol packet: OK.

MYSQLND_UH_MYSQLND_PROT_EOF_PACKET (int)
MySQL Client Server protocol packet: EOF.

MYSQLND_UH_MYSQLND_PROT_CMD_PACKET (int)
MySQL Client Server protocol packet: command.

MYSQLND_UH_MYSQLND_PROT_RSET_HEADER_PACKET (int)
MySQL Client Server protocol packet: result set header.

MYSQLND_UH_MYSQLND_PROT_RSET_FLD_PACKET (int)
MySQL Client Server protocol packet: resultset field.

MYSQLND_UH_MYSQLND_PROT_ROW_PACKET (int)
MySQL Client Server protocol packet: row.

MYSQLND_UH_MYSQLND_PROT_STATS_PACKET (int)
MySQL Client Server protocol packet: stats.

MYSQLND_UH_MYSQLND_PREPARE_RESP_PACKET (int)
MySQL Client Server protocol packet: prepare response.

MYSQLND_UH_MYSQLND_CHG_USER_RESP_PACKET (int)
MySQL Client Server protocol packet: change user response.

MYSQLND_UH_MYSQLND_PROT_LAST (int)
No practical meaning. Last entry marker of internal C data structure list.

MysqlndUhConnection::close related

The following constants can be used to detect why a connection has been closed through MysqlndUhConnection::close().

MYSQLND_UH_MYSQLND_CLOSE_EXPLICIT (int)
User has called mysqlnd to close the connection.

MYSQLND_UH_MYSQLND_CLOSE_IMPLICIT (int)
Implicitly closed, for example, during garbage connection.

MYSQLND_UH_MYSQLND_CLOSE_DISCONNECTED (int)
Connection error.

MYSQLND_UH_MYSQLND_CLOSE_LAST (int)
No practical meaning. Last entry marker of internal C data structure list.

MysqlndUhConnection::setServerOption() related

The following constants can be used to detect which option is set through MysqlndUhConnection::setServerOption().

MYSQLND_UH_SERVER_OPTION_MULTI_STATEMENTS_ON (int)
Option: enables multi statement support.

MYSQLND_UH_SERVER_OPTION_MULTI_STATEMENTS_OFF (int)
Option: disables multi statement support.

MysqlndUhConnection::setClientOption related

The following constants can be used to detect which option is set through <span class="methodname">MysqlndUhConnection::setClientOption.

MYSQLND_UH_MYSQLND_OPTION_OPT_CONNECT_TIMEOUT (int)
Option: connection timeout.

MYSQLND_UH_MYSQLND_OPTION_OPT_COMPRESS (int)
Option: whether the MySQL compressed protocol is to be used.

MYSQLND_UH_MYSQLND_OPTION_OPT_NAMED_PIPE (int)
Option: named pipe to use for connection (Windows).

MYSQLND_UH_MYSQLND_OPTION_INIT_COMMAND (int)
Option: init command to execute upon connect.

MYSQLND_UH_MYSQLND_READ_DEFAULT_FILE (int)
Option: MySQL server default file to read upon connect.

MYSQLND_UH_MYSQLND_READ_DEFAULT_GROUP (int)
Option: MySQL server default file group to read upon connect.

MYSQLND_UH_MYSQLND_SET_CHARSET_DIR (int)
Option: charset description files directory.

MYSQLND_UH_MYSQLND_SET_CHARSET_NAME (int)
Option: charset name.

MYSQLND_UH_MYSQLND_OPT_LOCAL_INFILE (int)
Option: Whether to allow LOAD DATA LOCAL INFILE use.

MYSQLND_UH_MYSQLND_OPT_PROTOCOL (int)
Option: supported protocol version.

MYSQLND_UH_MYSQLND_SHARED_MEMORY_BASE_NAME (int)
Option: shared memory base name for shared memory connections.

MYSQLND_UH_MYSQLND_OPT_READ_TIMEOUT (int)
Option: connection read timeout.

MYSQLND_UH_MYSQLND_OPT_WRITE_TIMEOUT (int)
Option: connection write timeout.

MYSQLND_UH_MYSQLND_OPT_USE_RESULT (int)
Option: unbuffered result sets.

MYSQLND_UH_MYSQLND_OPT_USE_REMOTE_CONNECTION (int)
Embedded server related.

MYSQLND_UH_MYSQLND_OPT_USE_EMBEDDED_CONNECTION (int)
Embedded server related.

MYSQLND_UH_MYSQLND_OPT_GUESS_CONNECTION (int)
TODO

MYSQLND_UH_MYSQLND_SET_CLIENT_IP (int)
TODO

MYSQLND_UH_MYSQLND_SECURE_AUTH (int)
TODO

MYSQLND_UH_MYSQLND_REPORT_DATA_TRUNCATION (int)
Option: Whether to report data truncation.

MYSQLND_UH_MYSQLND_OPT_RECONNECT (int)
Option: Whether to reconnect automatically.

MYSQLND_UH_MYSQLND_OPT_SSL_VERIFY_SERVER_CERT (int)
Option: TODO

MYSQLND_UH_MYSQLND_OPT_NET_CMD_BUFFER_SIZE (int)
Option: mysqlnd network buffer size for commands.

MYSQLND_UH_MYSQLND_OPT_NET_READ_BUFFER_SIZE (int)
Option: mysqlnd network buffer size for reading from the server.

MYSQLND_UH_MYSQLND_OPT_SSL_KEY (int)
Option: SSL key.

MYSQLND_UH_MYSQLND_OPT_SSL_CERT (int)
Option: SSL certificate.

MYSQLND_UH_MYSQLND_OPT_SSL_CA (int)
Option: SSL CA.

MYSQLND_UH_MYSQLND_OPT_SSL_CAPATH (int)
Option: Path to SSL CA.

MYSQLND_UH_MYSQLND_OPT_SSL_CIPHER (int)
Option: SSL cipher.

MYSQLND_UH_MYSQLND_OPT_SSL_PASSPHRASE (int)
Option: SSL passphrase.

MYSQLND_UH_SERVER_OPTION_PLUGIN_DIR (int)
Option: server plugin directory.

MYSQLND_UH_SERVER_OPTION_DEFAULT_AUTH (int)
Option: default authentication method.

MYSQLND_UH_SERVER_OPTION_SET_CLIENT_IP (int)
TODO

MYSQLND_UH_MYSQLND_OPT_MAX_ALLOWED_PACKET (int)
Option: maximum allowed packet size. Available as of PHP 5.4.0.

MYSQLND_UH_MYSQLND_OPT_AUTH_PROTOCOL (int)
Option: TODO. Available as of PHP 5.4.0.

MYSQLND_UH_MYSQLND_OPT_INT_AND_FLOAT_NATIVE (int)
Option: make mysqlnd return integer and float columns as long even when using the MySQL Client Server text protocol. Only available with a custom build of mysqlnd.

Other

The plugins version number can be obtained using MYSQLND_UH_VERSION or MYSQLND_UH_VERSION_ID. MYSQLND_UH_VERSION is the string representation of the numerical version number MYSQLND_UH_VERSION_ID, which is an integer such as 10000. Developers can calculate the version number as follows.

Version (part) Example
Major*10000 1*10000 = 10000
Minor*100 0*100 = 0
Patch 0 = 0
MYSQLND_UH_VERSION_ID 10000

MYSQLND_UH_VERSION (string)
Plugin version string, for example, “1.0.0-alpha”.

MYSQLND_UH_VERSION_ID (int)
Plugin version number, for example, 10000.

简介

类摘要

MysqlndUhConnection

class MysqlndUhConnection {

/* 方法 */

public bool changeUser ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">string $user , <span class="methodparam">string $password , string $database , <span class="type">bool $silent , <span class="methodparam">int $passwd_len )

public string charsetName ( <span class="methodparam">mysqlnd_connection $connection )

public bool close ( <span class="type">mysqlnd_connection $connection , <span class="methodparam">int $close_type )

public bool connect ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">string $host , <span class="methodparam">string $use" , string $password , <span class="type">string $database , <span class="methodparam">int $port , <span class="methodparam">string $socket , int $mysql_flags )

public <span class="methodname">__construct ( <span class="methodparam">void )

public bool endPSession ( <span class="methodparam">mysqlnd_connection $connection )

public string escapeString ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">string $escape_string )

public int <span class="methodname">getAffectedRows ( <span class="methodparam">mysqlnd_connection $connection )

public int <span class="methodname">getErrorNumber ( <span class="methodparam">mysqlnd_connection $connection )

public string getErrorString ( <span class="methodparam">mysqlnd_connection $connection )

public int <span class="methodname">getFieldCount ( <span class="methodparam">mysqlnd_connection $connection )

public string getHostInformation ( <span class="methodparam">mysqlnd_connection $connection )

public int <span class="methodname">getLastInsertId ( <span class="methodparam">mysqlnd_connection $connection )

public void getLastMessage ( <span class="methodparam">mysqlnd_connection $connection )

public string getProtocolInformation ( <span class="methodparam">mysqlnd_connection $connection )

public string getServerInformation ( <span class="methodparam">mysqlnd_connection $connection )

public string getServerStatistics ( <span class="methodparam">mysqlnd_connection $connection )

public int <span class="methodname">getServerVersion ( <span class="methodparam">mysqlnd_connection $connection )

public string getSqlstate ( <span class="methodparam">mysqlnd_connection $connection )

public array getStatistics ( <span class="methodparam">mysqlnd_connection $connection )

public int <span class="methodname">getThreadId ( <span class="type">mysqlnd_connection $connection )

public int <span class="methodname">getWarningCount ( <span class="methodparam">mysqlnd_connection $connection )

public bool init ( <span class="type">mysqlnd_connection $connection )

public bool killConnection ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">int $pid )

public array listFields ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">string $table , <span class="methodparam">string $achtung_wild )

public void listMethod ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">string $query , <span class="methodparam">string $achtung_wild , <span class="type">string $par1 )

public bool moreResults ( <span class="methodparam">mysqlnd_connection $connection )

public bool nextResult ( <span class="methodparam">mysqlnd_connection $connection )

public bool ping ( <span class="type">mysqlnd_connection $connection )

public bool query ( <span class="type">mysqlnd_connection $connection , <span class="methodparam">string $query )

public bool queryReadResultsetHeader ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">mysqlnd_statement $mysqlnd_stmt )

public bool reapQuery ( <span class="methodparam">mysqlnd_connection $connection )

public bool refreshServer ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">int $options )

public bool restartPSession ( <span class="methodparam">mysqlnd_connection $connection )

public bool selectDb ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">string $database )

public bool sendClose ( <span class="methodparam">mysqlnd_connection $connection )

public bool sendQuery ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">string $query )

public bool serverDumpDebugInformation ( <span class="methodparam">mysqlnd_connection $connection )

public bool setAutocommit ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">int $mode )

public bool setCharset ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">string $charset )

public bool setClientOption ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">int $option , <span class="methodparam">int $value )

public void setServerOption ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">int $option )

public void shutdownServer ( <span class="methodparam">string $MYSQLND_UH_RES_MYSQLND_NAME , <span class="type">string $level )

public bool simpleCommand ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">int $command , <span class="methodparam">string $arg , int $ok_packet , <span class="type">bool $silent , <span class="methodparam">bool $ignore_upsert_status )

public bool simpleCommandHandleResponse ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">int $ok_packet , <span class="methodparam">bool $silent , int $command , <span class="type">bool $ignore_upsert_status )

public bool sslSet ( <span class="type">mysqlnd_connection $connection , <span class="methodparam">string $key , string $cert , <span class="type">string $ca , <span class="methodparam">string $capath , string $cipher )

public resource stmtInit ( <span class="methodparam">mysqlnd_connection $connection )

public resource storeResult ( <span class="methodparam">mysqlnd_connection $connection )

public bool txCommit ( <span class="methodparam">mysqlnd_connection $connection )

public bool txRollback ( <span class="methodparam">mysqlnd_connection $connection )

public resource useResult ( <span class="methodparam">mysqlnd_connection $connection )

}

MysqlndUhConnection::changeUser

Changes the user of the specified mysqlnd database connection

说明

public bool MysqlndUhConnection::changeUser ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">string $user , <span class="methodparam">string $password , string $database , <span class="type">bool $silent , <span class="methodparam">int $passwd_len )

Changes the user of the specified mysqlnd database connection

参数

connection
Mysqlnd connection handle. Do not modify!

user
The MySQL user name.

password
The MySQL password.

database
The MySQL database to change to.

silent
Controls if mysqlnd is allowed to emit errors or not.

passwd_len
Length of the MySQL password.

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 MysqlndUhConnection::changeUser example

<?php
class proxy extends MysqlndUhConnection {
 /* Hook mysqlnd's connection::change_user call */
 public function changeUser($res, $user, $passwd, $db, $silent, $passwd_len) {
   printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
   $ret = parent::changeUser($res, $user, $passwd, $db, $silent, $passwd_len);
   printf("%s returns %s\n", __METHOD__, var_export($ret, true));
   return $ret;
 }
}
/* Install proxy/hooks to be used with all future mysqlnd connection */
mysqlnd_uh_set_connection_proxy(new proxy());

/* Create mysqli connection which is using the mysqlnd library */
$mysqli = new mysqli("localhost", "root", "", "test");

/* Example of a user API call which triggers the hooked mysqlnd call */
var_dump($mysqli->change_user("root", "bar", "test"));
?>

以上例程会输出:

proxy::changeUser(array (
  0 => NULL,
  1 => 'root',
  2 => 'bar',
  3 => 'test',
  4 => false,
  5 => 3,
))
proxy::changeUser returns false
bool(false)

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_change_user

MysqlndUhConnection::charsetName

Returns the default character set for the database connection

说明

public string MysqlndUhConnection::charsetName ( <span class="methodparam">mysqlnd_connection $connection )

Returns the default character set for the database connection.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

The default character set.

范例

示例 #1 <span class="function">MysqlndUhConnection::charsetName example

<?php
class proxy extends MysqlndUhConnection {
  public function charsetName($res) {
   printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
   $ret = parent::charsetName($res);
   printf("%s returns %s\n", __METHOD__, var_export($ret, true));
   return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
var_dump(mysqli_character_set_name($mysqli));
?>

以上例程会输出:

proxy::charsetName(array (
  0 => NULL,
))
proxy::charsetName returns 'latin1'
string(6) "latin1"

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_character_set_name

MysqlndUhConnection::close

Closes a previously opened database connection

说明

public bool MysqlndUhConnection::close ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">int $close_type )

Closes a previously opened database connection.

Note:

Failing to call the parent implementation may cause memory leaks or crash PHP. This is not considered a bug. Please, keep in mind that the mysqlnd library functions have never been designed to be exposed to the user space.

参数

connection
The connection to be closed. Do not modify!

close_type
Why the connection is to be closed. The value of close_type is one of MYSQLND_UH_MYSQLND_CLOSE_EXPLICIT, MYSQLND_UH_MYSQLND_CLOSE_IMPLICIT, MYSQLND_UH_MYSQLND_CLOSE_DISCONNECTED or MYSQLND_UH_MYSQLND_CLOSE_LAST. The latter should never be seen, unless the default behaviour of the mysqlnd library has been changed by a plugin.

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 MysqlndUhConnection::close example

<?php
function close_type_to_string($close_type) {
 $mapping = array(
  MYSQLND_UH_MYSQLND_CLOSE_DISCONNECTED => "MYSQLND_UH_MYSQLND_CLOSE_DISCONNECTED",
  MYSQLND_UH_MYSQLND_CLOSE_EXPLICIT => "MYSQLND_UH_MYSQLND_CLOSE_EXPLICIT",
  MYSQLND_UH_MYSQLND_CLOSE_IMPLICIT => "MYSQLND_UH_MYSQLND_CLOSE_IMPLICIT",
  MYSQLND_UH_MYSQLND_CLOSE_LAST => "MYSQLND_UH_MYSQLND_CLOSE_IMPLICIT"
 );
 return (isset($mapping[$close_type])) ? $mapping[$close_type] : 'unknown';
}

class proxy extends MysqlndUhConnection {
  public function close($res, $close_type) {
   printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
   printf("close_type = %s\n", close_type_to_string($close_type));
   /* WARNING: you must call the parent */
   $ret = parent::close($res, $close_type);
   printf("%s returns %s\n", __METHOD__, var_export($ret, true));
   return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->close();
?>

以上例程会输出:

proxy::close(array (
  0 => NULL,
  1 => 0,
))
close_type = MYSQLND_UH_MYSQLND_CLOSE_EXPLICIT
proxy::close returns true

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_close
  • mysql_close

MysqlndUhConnection::connect

Open a new connection to the MySQL server

说明

public bool MysqlndUhConnection::connect ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">string $host , <span class="methodparam">string $use" , string $password , <span class="type">string $database , <span class="methodparam">int $port , <span class="methodparam">string $socket , int $mysql_flags )

Open a new connection to the MySQL server.

参数

connection
Mysqlnd connection handle. Do not modify!

host
Can be either a host name or an IP address. Passing the NULL value or the string "localhost" to this parameter, the local host is assumed. When possible, pipes will be used instead of the TCP/IP protocol.

user
The MySQL user name.

password
If not provided or null, the MySQL server will attempt to authenticate the user against those user records which have no password only. This allows one username to be used with different permissions (depending on if a password as provided or not).

database
If provided will specify the default database to be used when performing queries.

port
Specifies the port number to attempt to connect to the MySQL server.

socket
Specifies the socket or named pipe that should be used. If null, mysqlnd will default to /tmp/mysql.sock.

mysql_flags
Connection options.

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 MysqlndUhConnection::connect example

<?php
class proxy extends MysqlndUhConnection {
 public function connect($res, $host, $user, $passwd, $db, $port, $socket, $mysql_flags) {
   printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
   $ret = parent::connect($res, $host, $user, $passwd, $db, $port, $socket, $mysql_flags);
   printf("%s returns %s\n", __METHOD__, var_export($ret, true));
   return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
?>

以上例程会输出:

proxy::connect(array (
  0 => NULL,
  1 => 'localhost',
  2 => 'root',
  3 => '',
  4 => 'test',
  5 => 3306,
  6 => NULL,
  7 => 131072,
))
proxy::connect returns true

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_connect
  • mysql_connect

MysqlndUhConnection::__construct

The __construct purpose

说明

public <span class="methodname">MysqlndUhConnection::__construct ( <span class="methodparam">void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

MysqlndUhConnection::endPSession

End a persistent connection

说明

public bool MysqlndUhConnection::endPSession ( <span class="methodparam">mysqlnd_connection $connection )

End a persistent connection

Warning

本函数还未编写文档,仅有参数列表。

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 <span class="function">MysqlndUhConnection::endPSession example

<?php
class proxy extends MysqlndUhConnection {
 public function endPSession($conn) {
   printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
   $ret = parent::endPSession($conn);
   printf("%s returns %s\n", __METHOD__, var_export($ret, true));
   return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("p:localhost", "root", "", "test");
$mysqli->close();
?>

以上例程会输出:

proxy::endPSession(array (
  0 => NULL,
))
proxy::endPSession returns true

参见

  • mysqlnd_uh_set_connection_proxy

MysqlndUhConnection::escapeString

Escapes special characters in a string for use in an SQL statement, taking into account the current charset of the connection

说明

public string MysqlndUhConnection::escapeString ( mysqlnd_connection $connection , <span class="type">string $escape_string )

Escapes special characters in a string for use in an SQL statement, taking into account the current charset of the connection.

参数

MYSQLND_UH_RES_MYSQLND_NAME
Mysqlnd connection handle. Do not modify!

escape_string
The string to be escaped.

返回值

The escaped string.

范例

示例 #1 <span class="function">MysqlndUhConnection::escapeString example

<?php
class proxy extends MysqlndUhConnection {
 public function escapeString($res, $string) {
   printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
   $ret = parent::escapeString($res, $string);
   printf("%s returns %s\n", __METHOD__, var_export($ret, true));
   return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->set_charset("latin1");
$mysqli->real_escape_string("test0'test");
?>

以上例程会输出:

proxy::escapeString(array (
  0 => NULL,
  1 => 'test0\'test',
))
proxy::escapeString returns 'test0\\\'test'

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_real_escape_string
  • mysql_real_escape_string

MysqlndUhConnection::getAffectedRows

Gets the number of affected rows in a previous MySQL operation

说明

public int <span class="methodname">MysqlndUhConnection::getAffectedRows ( <span class="methodparam">mysqlnd_connection $connection )

Gets the number of affected rows in a previous MySQL operation.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Number of affected rows.

范例

示例 #1 <span class="function">MysqlndUhConnection::getAffectedRows example

<?php
class proxy extends MysqlndUhConnection {
 public function getAffectedRows($res) {
   printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
   $ret = parent::getAffectedRows($res);
   printf("%s returns %s\n", __METHOD__, var_export($ret, true));
   return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1)");
var_dump($mysqli->affected_rows);
?>

以上例程会输出:

proxy::getAffectedRows(array (
  0 => NULL,
))
proxy::getAffectedRows returns 1
int(1)

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_affected_rows
  • mysql_affected_rows

MysqlndUhConnection::getErrorNumber

Returns the error code for the most recent function call

说明

public int <span class="methodname">MysqlndUhConnection::getErrorNumber ( <span class="methodparam">mysqlnd_connection $connection )

Returns the error code for the most recent function call.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Error code for the most recent function call.

范例

MysqlndUhConnection::getErrorNumber is not only executed after the invocation of a user space API call which maps directly to it but also called internally.

示例 #1 <span class="function">MysqlndUhConnection::getErrorNumber example

<?php
class proxy extends MysqlndUhConnection {
 public function getErrorNumber($res) {
   printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
   $ret = parent::getErrorNumber($res);
   printf("%s returns %s\n", __METHOD__, var_export($ret, true));
   return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

printf("connect...\n");
$mysqli = new mysqli("localhost", "root", "", "test");
printf("query...\n");
$mysqli->query("PLEASE_LET_THIS_BE_INVALID_SQL");
printf("errno...\n");
var_dump($mysqli->errno);
printf("close...\n");
$mysqli->close();
?>

以上例程会输出:

connect...
proxy::getErrorNumber(array (
  0 => NULL,
))
proxy::getErrorNumber returns 0
query...
errno...
proxy::getErrorNumber(array (
  0 => NULL,
))
proxy::getErrorNumber returns 1064
int(1064)
close...

参见

  • mysqlnd_uh_set_connection_proxy
  • MysqlndUhConnection::getErrorString
  • mysqli_errno
  • mysql_errno

MysqlndUhConnection::getErrorString

Returns a string description of the last error

说明

public string MysqlndUhConnection::getErrorString ( mysqlnd_connection $connection )

Returns a string description of the last error.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Error string for the most recent function call.

范例

MysqlndUhConnection::getErrorString is not only executed after the invocation of a user space API call which maps directly to it but also called internally.

示例 #1 <span class="function">MysqlndUhConnection::getErrorString example

<?php
class proxy extends MysqlndUhConnection {
 public function getErrorString($res) {
   printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
   $ret = parent::getErrorString($res);
   printf("%s returns %s\n", __METHOD__, var_export($ret, true));
   return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

printf("connect...\n");
$mysqli = new mysqli("localhost", "root", "", "test");
printf("query...\n");
$mysqli->query("WILL_I_EVER_LEARN_SQL?");
printf("errno...\n");
var_dump($mysqli->error);
printf("close...\n");
$mysqli->close();
?>

以上例程会输出:

connect...
proxy::getErrorString(array (
  0 => NULL,
))
proxy::getErrorString returns ''
query...
errno...
proxy::getErrorString(array (
  0 => NULL,
))
proxy::getErrorString returns 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'WILL_I_EVER_LEARN_SQL?\' at line 1'
string(168) "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WILL_I_EVER_LEARN_SQL?' at line 1"
close...

参见

  • mysqlnd_uh_set_connection_proxy
  • MysqlndUhConnection::getErrorNumber
  • mysqli_error
  • mysql_error

MysqlndUhConnection::getFieldCount

Returns the number of columns for the most recent query

说明

public int <span class="methodname">MysqlndUhConnection::getFieldCount ( <span class="methodparam">mysqlnd_connection $connection )

Returns the number of columns for the most recent query.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Number of columns.

范例

MysqlndUhConnection::getFieldCount is not only executed after the invocation of a user space API call which maps directly to it but also called internally.

示例 #1 <span class="function">MysqlndUhConnection::getFieldCount example

<?php
class proxy extends MysqlndUhConnection {
 public function getFieldCount($res) {
   printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
   $ret = parent::getFieldCount($res);
   printf("%s returns %s\n", __METHOD__, var_export($ret, true));
   return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->query("WILL_I_EVER_LEARN_SQL?");
var_dump($mysqli->field_count);
$mysqli->query("SELECT 1, 2, 3 FROM DUAL");
var_dump($mysqli->field_count);
?>

以上例程会输出:

proxy::getFieldCount(array (
  0 => NULL,
))
proxy::getFieldCount returns 0
int(0)
proxy::getFieldCount(array (
  0 => NULL,
))
proxy::getFieldCount returns 3
proxy::getFieldCount(array (
  0 => NULL,
))
proxy::getFieldCount returns 3
int(3)

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_field_count

MysqlndUhConnection::getHostInformation

Returns a string representing the type of connection used

说明

public string MysqlndUhConnection::getHostInformation ( <span class="type">mysqlnd_connection $connection )

Returns a string representing the type of connection used.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Connection description.

范例

示例 #1 <span class="function">MysqlndUhConnection::getHostInformation example

<?php
class proxy extends MysqlndUhConnection {
 public function getHostInformation($res) {
   printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
   $ret = parent::getHostInformation($res);
   printf("%s returns %s\n", __METHOD__, var_export($ret, true));
   return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
var_dump($mysqli->host_info);
?>

以上例程会输出:

proxy::getHostInformation(array (
  0 => NULL,
))
proxy::getHostInformation returns 'Localhost via UNIX socket'
string(25) "Localhost via UNIX socket"

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_get_host_info
  • mysql_get_host_info

MysqlndUhConnection::getLastInsertId

Returns the auto generated id used in the last query

说明

public int <span class="methodname">MysqlndUhConnection::getLastInsertId ( <span class="methodparam">mysqlnd_connection $connection )

Returns the auto generated id used in the last query.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Last insert id.

范例

示例 #1 <span class="function">MysqlndUhConnection::getLastInsertId example

<?php
class proxy extends MysqlndUhConnection {
 public function getLastInsertId($res) {
   printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
   $ret = parent::getLastInsertId($res);
   printf("%s returns %s\n", __METHOD__, var_export($ret, true));
   return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT AUTO_INCREMENT PRIMARY KEY, col VARCHAR(255))");
$mysqli->query("INSERT INTO test(col) VALUES ('a')");
var_dump($mysqli->insert_id);
?>

以上例程会输出:

proxy::getLastInsertId(array (
  0 => NULL,
))
proxy::getLastInsertId returns 1
int(1)

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_insert_id
  • mysql_insert_id

MysqlndUhConnection::getLastMessage

Retrieves information about the most recently executed query

说明

public void MysqlndUhConnection::getLastMessage ( mysqlnd_connection $connection )

Retrieves information about the most recently executed query.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Last message. Trying to return a string longer than 511 bytes will cause an error of the type E_WARNING and result in the string being truncated.

范例

示例 #1 <span class="function">MysqlndUhConnection::getLastMessage example

<?php
class proxy extends MysqlndUhConnection {
 public function getLastMessage($res) {
   printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
   $ret = parent::getLastMessage($res);
   printf("%s returns %s\n", __METHOD__, var_export($ret, true));
   return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
var_dump($mysqli->info);
$mysqli->query("DROP TABLE IF EXISTS test");
var_dump($mysqli->info);
?>

以上例程会输出:

proxy::getLastMessage(array (
  0 => NULL,
))
proxy::getLastMessage returns ''
string(0) ""
proxy::getLastMessage(array (
  0 => NULL,
))
proxy::getLastMessage returns ''
string(0) ""

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_info
  • mysql_info

MysqlndUhConnection::getProtocolInformation

Returns the version of the MySQL protocol used

说明

public string <span class="methodname">MysqlndUhConnection::getProtocolInformation ( mysqlnd_connection $connection )

Returns the version of the MySQL protocol used.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

The protocol version.

范例

示例 #1 <span class="function">MysqlndUhConnection::getProtocolInformation example

<?php
class proxy extends MysqlndUhConnection {
 public function getProtocolInformation($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::getProtocolInformation($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
var_dump($mysqli->protocol_version);
?>

以上例程会输出:

proxy::getProtocolInformation(array (
  0 => NULL,
))
proxy::getProtocolInformation returns 10
int(10)

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_get_proto_info
  • mysql_get_proto_info

MysqlndUhConnection::getServerInformation

Returns the version of the MySQL server

说明

public string <span class="methodname">MysqlndUhConnection::getServerInformation ( mysqlnd_connection $connection )

Returns the version of the MySQL server.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

The server version.

范例

示例 #1 <span class="function">MysqlndUhConnection::getServerInformation example

<?php
class proxy extends MysqlndUhConnection {
 public function getServerInformation($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::getServerInformation($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
var_dump($mysqli->server_info);
?>

以上例程会输出:

proxy::getServerInformation(array (
  0 => NULL,
))
proxy::getServerInformation returns '5.1.45-debug-log'
string(16) "5.1.45-debug-log"

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_get_server_info
  • mysql_get_server_info

MysqlndUhConnection::getServerStatistics

Gets the current system status

说明

public string MysqlndUhConnection::getServerStatistics ( <span class="type">mysqlnd_connection $connection )

Gets the current system status.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

The system status message.

范例

示例 #1 <span class="function">MysqlndUhConnection::getServerStatistics example

<?php
class proxy extends MysqlndUhConnection {
 public function getServerStatistics($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::getServerStatistics($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
var_dump(mysqli_stat($mysqli));
?>

以上例程会输出:

proxy::getServerStatistics(array (
  0 => NULL,
))
proxy::getServerStatistics returns 'Uptime: 2059995  Threads: 1  Questions: 126157  Slow queries: 0  Opens: 6377  Flush tables: 1  Open tables: 18  Queries per second avg: 0.61'
string(140) "Uptime: 2059995  Threads: 1  Questions: 126157  Slow queries: 0  Opens: 6377  Flush tables: 1  Open tables: 18  Queries per second avg: 0.61"

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_stat
  • mysql_stat

MysqlndUhConnection::getServerVersion

Returns the version of the MySQL server as an integer

说明

public int <span class="methodname">MysqlndUhConnection::getServerVersion ( <span class="methodparam">mysqlnd_connection $connection )

Returns the version of the MySQL server as an integer.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

The MySQL version.

范例

示例 #1 <span class="function">MysqlndUhConnection::getServerVersion example

<?php
class proxy extends MysqlndUhConnection {
 public function getServerVersion($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::getServerVersion($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
var_dump($mysqli->server_version);
?>

以上例程会输出:

proxy::getServerVersion(array (
  0 => NULL,
))
proxy::getServerVersion returns 50145
int(50145)

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_get_server_version
  • mysql_get_server_version

MysqlndUhConnection::getSqlstate

Returns the SQLSTATE error from previous MySQL operation

说明

public string MysqlndUhConnection::getSqlstate ( <span class="methodparam">mysqlnd_connection $connection )

Returns the SQLSTATE error from previous MySQL operation.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

The SQLSTATE code.

范例

示例 #1 <span class="function">MysqlndUhConnection::getSqlstate example

<?php
class proxy extends MysqlndUhConnection {
 public function getSqlstate($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::getSqlstate($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
var_dump($mysqli->sqlstate);
$mysqli->query("AN_INVALID_REQUEST_TO_PROVOKE_AN_ERROR");
var_dump($mysqli->sqlstate);
?>

以上例程会输出:

proxy::getSqlstate(array (
  0 => NULL,
))
proxy::getSqlstate returns '00000'
string(5) "00000"
proxy::getSqlstate(array (
  0 => NULL,
))
proxy::getSqlstate returns '42000'
string(5) "42000"

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_sql_state

MysqlndUhConnection::getStatistics

Returns statistics about the client connection

说明

public array MysqlndUhConnection::getStatistics ( mysqlnd_connection $connection )

Returns statistics about the client connection.

Warning

本函数还未编写文档,仅有参数列表。

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Connection statistics collected by mysqlnd.

范例

示例 #1 <span class="function">MysqlndUhConnection::getStatistics example

<?php
class proxy extends MysqlndUhConnection {
 public function getStatistics($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::getStatistics($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
var_dump($mysqli->get_connection_stats());
?>

以上例程会输出:

proxy::getStatistics(array (
  0 => NULL,
))
proxy::getStatistics returns array (
  'bytes_sent' => '73',
  'bytes_received' => '77',
  'packets_sent' => '2',
  'packets_received' => '2',
  'protocol_overhead_in' => '8',
  'protocol_overhead_out' => '8',
  'bytes_received_ok_packet' => '0',
  'bytes_received_eof_packet' => '0',
  'bytes_received_rset_header_packet' => '0',
  'bytes_received_rset_field_meta_packet' => '0',
  'bytes_received_rset_row_packet' => '0',
  'bytes_received_prepare_response_packet' => '0',
  'bytes_received_change_user_packet' => '0',
  'packets_sent_command' => '0',
  'packets_received_ok' => '0',
  'packets_received_eof' => '0',
  'packets_received_rset_header' => '0',
  'packets_received_rset_field_meta' => '0',
  'packets_received_rset_row' => '0',
  'packets_received_prepare_response' => '0',
  'packets_received_change_user' => '0',
  'result_set_queries' => '0',
  'non_result_set_queries' => '0',
  'no_index_used' => '0',
  'bad_index_used' => '0',
  'slow_queries' => '0',
  'buffered_sets' => '0',
  'unbuffered_sets' => '0',
  'ps_buffered_sets' => '0',
  'ps_unbuffered_sets' => '0',
  'flushed_normal_sets' => '0',
  'flushed_ps_sets' => '0',
  'ps_prepared_never_executed' => '0',
  'ps_prepared_once_executed' => '0',
  'rows_fetched_from_server_normal' => '0',
  'rows_fetched_from_server_ps' => '0',
  'rows_buffered_from_client_normal' => '0',
  'rows_buffered_from_client_ps' => '0',
  'rows_fetched_from_client_normal_buffered' => '0',
  'rows_fetched_from_client_normal_unbuffered' => '0',
  'rows_fetched_from_client_ps_buffered' => '0',
  'rows_fetched_from_client_ps_unbuffered' => '0',
  'rows_fetched_from_client_ps_cursor' => '0',
  'rows_affected_normal' => '0',
  'rows_affected_ps' => '0',
  'rows_skipped_normal' => '0',
  'rows_skipped_ps' => '0',
  'copy_on_write_saved' => '0',
  'copy_on_write_performed' => '0',
  'command_buffer_too_small' => '0',
  'connect_success' => '1',
  'connect_failure' => '0',
  'connection_reused' => '0',
  'reconnect' => '0',
  'pconnect_success' => '0',
  'active_connections' => '1',
  'active_persistent_connections' => '0',
  'explicit_close' => '0',
  'implicit_close' => '0',
  'disconnect_close' => '0',
  'in_middle_of_command_close' => '0',
  'explicit_free_result' => '0',
  'implicit_free_result' => '0',
  'explicit_stmt_close' => '0',
  'implicit_stmt_close' => '0',
  'mem_emalloc_count' => '0',
  'mem_emalloc_amount' => '0',
  'mem_ecalloc_count' => '0',
  'mem_ecalloc_amount' => '0',
  'mem_erealloc_count' => '0',
  'mem_erealloc_amount' => '0',
  'mem_efree_count' => '0',
  'mem_efree_amount' => '0',
  'mem_malloc_count' => '0',
  'mem_malloc_amount' => '0',
  'mem_calloc_count' => '0',
  'mem_calloc_amount' => '0',
  'mem_realloc_count' => '0',
  'mem_realloc_amount' => '0',
  'mem_free_count' => '0',
  'mem_free_amount' => '0',
  'mem_estrndup_count' => '0',
  'mem_strndup_count' => '0',
  'mem_estndup_count' => '0',
  'mem_strdup_count' => '0',
  'proto_text_fetched_null' => '0',
  'proto_text_fetched_bit' => '0',
  'proto_text_fetched_tinyint' => '0',
  'proto_text_fetched_short' => '0',
  'proto_text_fetched_int24' => '0',
  'proto_text_fetched_int' => '0',
  'proto_text_fetched_bigint' => '0',
  'proto_text_fetched_decimal' => '0',
  'proto_text_fetched_float' => '0',
  'proto_text_fetched_double' => '0',
  'proto_text_fetched_date' => '0',
  'proto_text_fetched_year' => '0',
  'proto_text_fetched_time' => '0',
  'proto_text_fetched_datetime' => '0',
  'proto_text_fetched_timestamp' => '0',
  'proto_text_fetched_string' => '0',
  'proto_text_fetched_blob' => '0',
  'proto_text_fetched_enum' => '0',
  'proto_text_fetched_set' => '0',
  'proto_text_fetched_geometry' => '0',
  'proto_text_fetched_other' => '0',
  'proto_binary_fetched_null' => '0',
  'proto_binary_fetched_bit' => '0',
  'proto_binary_fetched_tinyint' => '0',
  'proto_binary_fetched_short' => '0',
  'proto_binary_fetched_int24' => '0',
  'proto_binary_fetched_int' => '0',
  'proto_binary_fetched_bigint' => '0',
  'proto_binary_fetched_decimal' => '0',
  'proto_binary_fetched_float' => '0',
  'proto_binary_fetched_double' => '0',
  'proto_binary_fetched_date' => '0',
  'proto_binary_fetched_year' => '0',
  'proto_binary_fetched_time' => '0',
  'proto_binary_fetched_datetime' => '0',
  'proto_binary_fetched_timestamp' => '0',
  'proto_binary_fetched_string' => '0',
  'proto_binary_fetched_blob' => '0',
  'proto_binary_fetched_enum' => '0',
  'proto_binary_fetched_set' => '0',
  'proto_binary_fetched_geometry' => '0',
  'proto_binary_fetched_other' => '0',
  'init_command_executed_count' => '0',
  'init_command_failed_count' => '0',
  'com_quit' => '0',
  'com_init_db' => '0',
  'com_query' => '0',
  'com_field_list' => '0',
  'com_create_db' => '0',
  'com_drop_db' => '0',
  'com_refresh' => '0',
  'com_shutdown' => '0',
  'com_statistics' => '0',
  'com_process_info' => '0',
  'com_connect' => '0',
  'com_process_kill' => '0',
  'com_debug' => '0',
  'com_ping' => '0',
  'com_time' => '0',
  'com_delayed_insert' => '0',
  'com_change_user' => '0',
  'com_binlog_dump' => '0',
  'com_table_dump' => '0',
  'com_connect_out' => '0',
  'com_register_slave' => '0',
  'com_stmt_prepare' => '0',
  'com_stmt_execute' => '0',
  'com_stmt_send_long_data' => '0',
  'com_stmt_close' => '0',
  'com_stmt_reset' => '0',
  'com_stmt_set_option' => '0',
  'com_stmt_fetch' => '0',
  'com_deamon' => '0',
  'bytes_received_real_data_normal' => '0',
  'bytes_received_real_data_ps' => '0',
)
array(160) {
  ["bytes_sent"]=>
  string(2) "73"
  ["bytes_received"]=>
  string(2) "77"
  ["packets_sent"]=>
  string(1) "2"
  ["packets_received"]=>
  string(1) "2"
  ["protocol_overhead_in"]=>
  string(1) "8"
  ["protocol_overhead_out"]=>
  string(1) "8"
  ["bytes_received_ok_packet"]=>
  string(1) "0"
  ["bytes_received_eof_packet"]=>
  string(1) "0"
  ["bytes_received_rset_header_packet"]=>
  string(1) "0"
  ["bytes_received_rset_field_meta_packet"]=>
  string(1) "0"
  ["bytes_received_rset_row_packet"]=>
  string(1) "0"
  ["bytes_received_prepare_response_packet"]=>
  string(1) "0"
  ["bytes_received_change_user_packet"]=>
  string(1) "0"
  ["packets_sent_command"]=>
  string(1) "0"
  ["packets_received_ok"]=>
  string(1) "0"
  ["packets_received_eof"]=>
  string(1) "0"
  ["packets_received_rset_header"]=>
  string(1) "0"
  ["packets_received_rset_field_meta"]=>
  string(1) "0"
  ["packets_received_rset_row"]=>
  string(1) "0"
  ["packets_received_prepare_response"]=>
  string(1) "0"
  ["packets_received_change_user"]=>
  string(1) "0"
  ["result_set_queries"]=>
  string(1) "0"
  ["non_result_set_queries"]=>
  string(1) "0"
  ["no_index_used"]=>
  string(1) "0"
  ["bad_index_used"]=>
  string(1) "0"
  ["slow_queries"]=>
  string(1) "0"
  ["buffered_sets"]=>
  string(1) "0"
  ["unbuffered_sets"]=>
  string(1) "0"
  ["ps_buffered_sets"]=>
  string(1) "0"
  ["ps_unbuffered_sets"]=>
  string(1) "0"
  ["flushed_normal_sets"]=>
  string(1) "0"
  ["flushed_ps_sets"]=>
  string(1) "0"
  ["ps_prepared_never_executed"]=>
  string(1) "0"
  ["ps_prepared_once_executed"]=>
  string(1) "0"
  ["rows_fetched_from_server_normal"]=>
  string(1) "0"
  ["rows_fetched_from_server_ps"]=>
  string(1) "0"
  ["rows_buffered_from_client_normal"]=>
  string(1) "0"
  ["rows_buffered_from_client_ps"]=>
  string(1) "0"
  ["rows_fetched_from_client_normal_buffered"]=>
  string(1) "0"
  ["rows_fetched_from_client_normal_unbuffered"]=>
  string(1) "0"
  ["rows_fetched_from_client_ps_buffered"]=>
  string(1) "0"
  ["rows_fetched_from_client_ps_unbuffered"]=>
  string(1) "0"
  ["rows_fetched_from_client_ps_cursor"]=>
  string(1) "0"
  ["rows_affected_normal"]=>
  string(1) "0"
  ["rows_affected_ps"]=>
  string(1) "0"
  ["rows_skipped_normal"]=>
  string(1) "0"
  ["rows_skipped_ps"]=>
  string(1) "0"
  ["copy_on_write_saved"]=>
  string(1) "0"
  ["copy_on_write_performed"]=>
  string(1) "0"
  ["command_buffer_too_small"]=>
  string(1) "0"
  ["connect_success"]=>
  string(1) "1"
  ["connect_failure"]=>
  string(1) "0"
  ["connection_reused"]=>
  string(1) "0"
  ["reconnect"]=>
  string(1) "0"
  ["pconnect_success"]=>
  string(1) "0"
  ["active_connections"]=>
  string(1) "1"
  ["active_persistent_connections"]=>
  string(1) "0"
  ["explicit_close"]=>
  string(1) "0"
  ["implicit_close"]=>
  string(1) "0"
  ["disconnect_close"]=>
  string(1) "0"
  ["in_middle_of_command_close"]=>
  string(1) "0"
  ["explicit_free_result"]=>
  string(1) "0"
  ["implicit_free_result"]=>
  string(1) "0"
  ["explicit_stmt_close"]=>
  string(1) "0"
  ["implicit_stmt_close"]=>
  string(1) "0"
  ["mem_emalloc_count"]=>
  string(1) "0"
  ["mem_emalloc_amount"]=>
  string(1) "0"
  ["mem_ecalloc_count"]=>
  string(1) "0"
  ["mem_ecalloc_amount"]=>
  string(1) "0"
  ["mem_erealloc_count"]=>
  string(1) "0"
  ["mem_erealloc_amount"]=>
  string(1) "0"
  ["mem_efree_count"]=>
  string(1) "0"
  ["mem_efree_amount"]=>
  string(1) "0"
  ["mem_malloc_count"]=>
  string(1) "0"
  ["mem_malloc_amount"]=>
  string(1) "0"
  ["mem_calloc_count"]=>
  string(1) "0"
  ["mem_calloc_amount"]=>
  string(1) "0"
  ["mem_realloc_count"]=>
  string(1) "0"
  ["mem_realloc_amount"]=>
  string(1) "0"
  ["mem_free_count"]=>
  string(1) "0"
  ["mem_free_amount"]=>
  string(1) "0"
  ["mem_estrndup_count"]=>
  string(1) "0"
  ["mem_strndup_count"]=>
  string(1) "0"
  ["mem_estndup_count"]=>
  string(1) "0"
  ["mem_strdup_count"]=>
  string(1) "0"
  ["proto_text_fetched_null"]=>
  string(1) "0"
  ["proto_text_fetched_bit"]=>
  string(1) "0"
  ["proto_text_fetched_tinyint"]=>
  string(1) "0"
  ["proto_text_fetched_short"]=>
  string(1) "0"
  ["proto_text_fetched_int24"]=>
  string(1) "0"
  ["proto_text_fetched_int"]=>
  string(1) "0"
  ["proto_text_fetched_bigint"]=>
  string(1) "0"
  ["proto_text_fetched_decimal"]=>
  string(1) "0"
  ["proto_text_fetched_float"]=>
  string(1) "0"
  ["proto_text_fetched_double"]=>
  string(1) "0"
  ["proto_text_fetched_date"]=>
  string(1) "0"
  ["proto_text_fetched_year"]=>
  string(1) "0"
  ["proto_text_fetched_time"]=>
  string(1) "0"
  ["proto_text_fetched_datetime"]=>
  string(1) "0"
  ["proto_text_fetched_timestamp"]=>
  string(1) "0"
  ["proto_text_fetched_string"]=>
  string(1) "0"
  ["proto_text_fetched_blob"]=>
  string(1) "0"
  ["proto_text_fetched_enum"]=>
  string(1) "0"
  ["proto_text_fetched_set"]=>
  string(1) "0"
  ["proto_text_fetched_geometry"]=>
  string(1) "0"
  ["proto_text_fetched_other"]=>
  string(1) "0"
  ["proto_binary_fetched_null"]=>
  string(1) "0"
  ["proto_binary_fetched_bit"]=>
  string(1) "0"
  ["proto_binary_fetched_tinyint"]=>
  string(1) "0"
  ["proto_binary_fetched_short"]=>
  string(1) "0"
  ["proto_binary_fetched_int24"]=>
  string(1) "0"
  ["proto_binary_fetched_int"]=>
  string(1) "0"
  ["proto_binary_fetched_bigint"]=>
  string(1) "0"
  ["proto_binary_fetched_decimal"]=>
  string(1) "0"
  ["proto_binary_fetched_float"]=>
  string(1) "0"
  ["proto_binary_fetched_double"]=>
  string(1) "0"
  ["proto_binary_fetched_date"]=>
  string(1) "0"
  ["proto_binary_fetched_year"]=>
  string(1) "0"
  ["proto_binary_fetched_time"]=>
  string(1) "0"
  ["proto_binary_fetched_datetime"]=>
  string(1) "0"
  ["proto_binary_fetched_timestamp"]=>
  string(1) "0"
  ["proto_binary_fetched_string"]=>
  string(1) "0"
  ["proto_binary_fetched_blob"]=>
  string(1) "0"
  ["proto_binary_fetched_enum"]=>
  string(1) "0"
  ["proto_binary_fetched_set"]=>
  string(1) "0"
  ["proto_binary_fetched_geometry"]=>
  string(1) "0"
  ["proto_binary_fetched_other"]=>
  string(1) "0"
  ["init_command_executed_count"]=>
  string(1) "0"
  ["init_command_failed_count"]=>
  string(1) "0"
  ["com_quit"]=>
  string(1) "0"
  ["com_init_db"]=>
  string(1) "0"
  ["com_query"]=>
  string(1) "0"
  ["com_field_list"]=>
  string(1) "0"
  ["com_create_db"]=>
  string(1) "0"
  ["com_drop_db"]=>
  string(1) "0"
  ["com_refresh"]=>
  string(1) "0"
  ["com_shutdown"]=>
  string(1) "0"
  ["com_statistics"]=>
  string(1) "0"
  ["com_process_info"]=>
  string(1) "0"
  ["com_connect"]=>
  string(1) "0"
  ["com_process_kill"]=>
  string(1) "0"
  ["com_debug"]=>
  string(1) "0"
  ["com_ping"]=>
  string(1) "0"
  ["com_time"]=>
  string(1) "0"
  ["com_delayed_insert"]=>
  string(1) "0"
  ["com_change_user"]=>
  string(1) "0"
  ["com_binlog_dump"]=>
  string(1) "0"
  ["com_table_dump"]=>
  string(1) "0"
  ["com_connect_out"]=>
  string(1) "0"
  ["com_register_slave"]=>
  string(1) "0"
  ["com_stmt_prepare"]=>
  string(1) "0"
  ["com_stmt_execute"]=>
  string(1) "0"
  ["com_stmt_send_long_data"]=>
  string(1) "0"
  ["com_stmt_close"]=>
  string(1) "0"
  ["com_stmt_reset"]=>
  string(1) "0"
  ["com_stmt_set_option"]=>
  string(1) "0"
  ["com_stmt_fetch"]=>
  string(1) "0"
  ["com_deamon"]=>
  string(1) "0"
  ["bytes_received_real_data_normal"]=>
  string(1) "0"
  ["bytes_received_real_data_ps"]=>
  string(1) "0"
}

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_get_connection_stats

MysqlndUhConnection::getThreadId

Returns the thread ID for the current connection

说明

public int <span class="methodname">MysqlndUhConnection::getThreadId ( <span class="methodparam">mysqlnd_connection $connection )

Returns the thread ID for the current connection.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Connection thread id.

范例

示例 #1 <span class="function">MysqlndUhConnection::getThreadId example

<?php
class proxy extends MysqlndUhConnection {
 public function getThreadId($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::getThreadId($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
var_dump($mysqli->thread_id);
?>

以上例程会输出:

proxy::getThreadId(array (
  0 => NULL,
))
proxy::getThreadId returns 27646
int(27646)

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_thread_id
  • mysql_thread_id

MysqlndUhConnection::getWarningCount

Returns the number of warnings from the last query for the given link

说明

public int <span class="methodname">MysqlndUhConnection::getWarningCount ( <span class="methodparam">mysqlnd_connection $connection )

Returns the number of warnings from the last query for the given link.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Number of warnings.

范例

示例 #1 <span class="function">MysqlndUhConnection::getWarningCount example

<?php
class proxy extends MysqlndUhConnection {
 public function getWarningCount($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::getWarningCount($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
var_dump($mysqli->warning_count);
?>

以上例程会输出:

proxy::getWarningCount(array (
  0 => NULL,
))
proxy::getWarningCount returns 0
int(0)

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_warning_count

MysqlndUhConnection::init

Initialize mysqlnd connection

说明

public bool MysqlndUhConnection::init ( <span class="methodparam">mysqlnd_connection $connection )

Initialize mysqlnd connection. This is an mysqlnd internal call to initialize the connection object.

Note:

Failing to call the parent implementation may cause memory leaks or crash PHP. This is not considered a bug. Please, keep in mind that the mysqlnd library functions have never been designed to be exposed to the user space.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 MysqlndUhConnection::init example

<?php
class proxy extends MysqlndUhConnection {
 public function init($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::init($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
?>

以上例程会输出:

proxy::init(array (
  0 => NULL,
))
proxy::init returns true

参见

  • mysqlnd_uh_set_connection_proxy

MysqlndUhConnection::killConnection

Asks the server to kill a MySQL thread

说明

public bool MysqlndUhConnection::killConnection ( mysqlnd_connection $connection , <span class="type">int $pid )

Asks the server to kill a MySQL thread.

参数

connection
Mysqlnd connection handle. Do not modify!

pid
Thread Id of the connection to be killed.

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 MysqlndUhConnection::kill example

<?php
class proxy extends MysqlndUhConnection {
 public function killConnection($res, $pid) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::killConnection($res, $pid);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->kill($mysqli->thread_id);
?>

以上例程会输出:

proxy::killConnection(array (
  0 => NULL,
  1 => 27650,
))
proxy::killConnection returns true

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_kill

MysqlndUhConnection::listFields

List MySQL table fields

说明

public array MysqlndUhConnection::listFields ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">string $table , <span class="methodparam">string $achtung_wild )

List MySQL table fields.

Warning

本函数还未编写文档,仅有参数列表。

参数

connection
Mysqlnd connection handle. Do not modify!

table
The name of the table that's being queried.

pattern
Name pattern.

返回值

范例

示例 #1 MysqlndUhConnection::listFields example

<?php
class proxy extends MysqlndUhConnection {
 public function listFields($res, $table, $pattern) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::listFields($res, $table, $pattern);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysql = mysql_connect("localhost", "root", "");
mysql_select_db("test", $mysql);
mysql_query("DROP TABLE IF EXISTS test_a", $mysql);
mysql_query("CREATE TABLE test_a(id INT, col1 VARCHAR(255))", $mysql);
$res = mysql_list_fields("test", "test_a", $mysql);
printf("num_rows = %d\n", mysql_num_rows($res));
while ($row = mysql_fetch_assoc($res))
 var_dump($row);
?>

以上例程会输出:

proxy::listFields(array (
  0 => NULL,
  1 => 'test_a',
  2 => '',
))
proxy::listFields returns NULL
num_rows = 0

参见

  • mysqlnd_uh_set_connection_proxy
  • mysql_list_fields

MysqlndUhConnection::listMethod

Wrapper for assorted list commands

说明

public void MysqlndUhConnection::listMethod ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">string $query , <span class="methodparam">string $achtung_wild , <span class="type">string $par1 )

Wrapper for assorted list commands.

Warning

本函数还未编写文档,仅有参数列表。

参数

connection
Mysqlnd connection handle. Do not modify!

query
SHOW command to be executed.

achtung_wild

par1

返回值

返回值

TODO

范例

示例 #1 MysqlndUhConnection::listMethod example

<?php
class proxy extends MysqlndUhConnection {
 public function listMethod($res, $query, $pattern, $par1) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::listMethod($res, $query, $pattern, $par1);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysql = mysql_connect("localhost", "root", "");
$res = mysql_list_dbs($mysql);
printf("num_rows = %d\n", mysql_num_rows($res));
while ($row = mysql_fetch_assoc($res))
 var_dump($row);
?>

以上例程会输出:

proxy::listMethod(array (
  0 => NULL,
  1 => 'SHOW DATABASES',
  2 => '',
  3 => '',
))
proxy::listMethod returns NULL
num_rows = 6
array(1) {
  ["Database"]=>
  string(18) "information_schema"
}
array(1) {
  ["Database"]=>
  string(5) "mysql"
}
array(1) {
  ["Database"]=>
  string(8) "oxid_new"
}
array(1) {
  ["Database"]=>
  string(7) "phptest"
}
array(1) {
  ["Database"]=>
  string(7) "pushphp"
}
array(1) {
  ["Database"]=>
  string(4) "test"
}

参见

  • mysqlnd_uh_set_connection_proxy
  • mysql_list_dbs

MysqlndUhConnection::moreResults

Check if there are any more query results from a multi query

说明

public bool MysqlndUhConnection::moreResults ( <span class="methodparam">mysqlnd_connection $connection )

Check if there are any more query results from a multi query.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 <span class="function">MysqlndUhConnection::moreResults example

<?php
class proxy extends MysqlndUhConnection {
 public function moreResults($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::moreResults($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->multi_query("SELECT 1 AS _one; SELECT 2 AS _two");
do {
  $res = $mysqli->store_result();
  var_dump($res->fetch_assoc());
  printf("%s\n", str_repeat("-", 40));
} while ($mysqli->more_results() && $mysqli->next_result());
?>

以上例程会输出:

array(1) {
  ["_one"]=>
  string(1) "1"
}
----------------------------------------
proxy::moreResults(array (
  0 => NULL,
))
proxy::moreResults returns true
proxy::moreResults(array (
  0 => NULL,
))
proxy::moreResults returns true
array(1) {
  ["_two"]=>
  string(1) "2"
}
----------------------------------------
proxy::moreResults(array (
  0 => NULL,
))
proxy::moreResults returns false

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_more_results

MysqlndUhConnection::nextResult

Prepare next result from multi_query

说明

public bool MysqlndUhConnection::nextResult ( <span class="methodparam">mysqlnd_connection $connection )

Prepare next result from multi_query.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 MysqlndUhConnection::nextResult example

<?php
class proxy extends MysqlndUhConnection {
 public function nextResult($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::nextResult($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->multi_query("SELECT 1 AS _one; SELECT 2 AS _two");
do {
  $res = $mysqli->store_result();
  var_dump($res->fetch_assoc());
  printf("%s\n", str_repeat("-", 40));
} while ($mysqli->more_results() && $mysqli->next_result());
?>

以上例程会输出:

array(1) {
  ["_one"]=>
  string(1) "1"
}
----------------------------------------
proxy::nextResult(array (
  0 => NULL,
))
proxy::nextResult returns true
array(1) {
  ["_two"]=>
  string(1) "2"
}
----------------------------------------

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_next_result

MysqlndUhConnection::ping

Pings a server connection, or tries to reconnect if the connection has gone down

说明

public bool MysqlndUhConnection::ping ( <span class="methodparam">mysqlnd_connection $connection )

Pings a server connection, or tries to reconnect if the connection has gone down.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 MysqlndUhConnection::ping example

<?php
class proxy extends MysqlndUhConnection {
 public function ping($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::ping($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->ping();
?>

以上例程会输出:

proxy::ping(array (
  0 => NULL,
))
proxy::ping returns true

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_ping
  • mysql_ping

MysqlndUhConnection::query

Performs a query on the database

说明

public bool MysqlndUhConnection::query ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">string $query )

Performs a query on the database (COM_QUERY).

参数

connection
Mysqlnd connection handle. Do not modify!

query
The query string.

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 MysqlndUhConnection::query example

<?php
class proxy extends MysqlndUhConnection {
 public function query($res, $query) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $query = "SELECT 'How about query rewriting?'";
  $ret = parent::query($res, $query);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$res = $mysqli->query("SELECT 'Welcome mysqlnd_uh!' FROM DUAL");
var_dump($res->fetch_assoc());
?>

以上例程会输出:

proxy::query(array (
  0 => NULL,
  1 => 'SELECT \'Welcome mysqlnd_uh!\' FROM DUAL',
))
proxy::query returns true
array(1) {
  ["How about query rewriting?"]=>
  string(26) "How about query rewriting?"
}

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_query
  • mysql_query

MysqlndUhConnection::queryReadResultsetHeader

Read a result set header

说明

public bool <span class="methodname">MysqlndUhConnection::queryReadResultsetHeader ( <span class="type">mysqlnd_connection $connection , <span class="methodparam">mysqlnd_statement $mysqlnd_stmt )

Read a result set header.

参数

connection
Mysqlnd connection handle. Do not modify!

mysqlnd_stmt
Mysqlnd statement handle. Do not modify! Set to null, if function is not used in the context of a prepared statement.

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 <span class="function">MysqlndUhConnection::queryReadResultsetHeader example

<?php
class proxy extends MysqlndUhConnection {
 public function queryReadResultsetHeader($res, $stmt) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::queryReadResultsetHeader($res, $stmt);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$res = $mysqli->query("SELECT 'Welcome mysqlnd_uh!' FROM DUAL");
var_dump($res->fetch_assoc());
?>

以上例程会输出:

proxy::queryReadResultsetHeader(array (
  0 => NULL,
  1 => NULL,
))
proxy::queryReadResultsetHeader returns true
array(1) {
  ["Welcome mysqlnd_uh!"]=>
  string(19) "Welcome mysqlnd_uh!"
}

参见

  • mysqlnd_uh_set_connection_proxy

MysqlndUhConnection::reapQuery

Get result from async query

说明

public bool MysqlndUhConnection::reapQuery ( <span class="methodparam">mysqlnd_connection $connection )

Get result from async query.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 MysqlndUhConnection::reapQuery example

<?php
class proxy extends MysqlndUhConnection {
 public function reapQuery($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::reapQuery($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$conn1 = new mysqli("localhost", "root", "", "test");
$conn2 = new mysqli("localhost", "root", "", "test");

$conn1->query("SELECT 1 as 'one', SLEEP(1) AS _sleep FROM DUAL", MYSQLI_ASYNC |  MYSQLI_USE_RESULT);
$conn2->query("SELECT 1.1 as 'one dot one' FROM DUAL", MYSQLI_ASYNC |  MYSQLI_USE_RESULT);

$links = array(
 $conn1->thread_id => array('link' => $conn1, 'processed' => false),
 $conn2->thread_id => array('link' => $conn2, 'processed' => false)
);

$saved_errors = array();
do {
 $poll_links = $poll_errors = $poll_reject = array();
 foreach ($links as $thread_id => $link) {
  if (!$link['processed']) {
   $poll_links[] = $link['link'];
   $poll_errors[] = $link['link'];
   $poll_reject[] = $link['link'];
  }
 }
 if (0 == count($poll_links))
  break;

 if (0 == ($num_ready = mysqli_poll($poll_links, $poll_errors, $poll_reject, 0, 200000)))
  continue;

 if (!empty($poll_errors)) {
  die(var_dump($poll_errors));
 }

 foreach ($poll_links as $link) {
  $thread_id = mysqli_thread_id($link);
  $links[$thread_id]['processed'] = true;

  if (is_object($res = mysqli_reap_async_query($link))) {
   // result set object
   while ($row = mysqli_fetch_assoc($res)) {
    // eat up all results
    var_dump($row);
   }
   mysqli_free_result($res);
  } else {
   // either there is no result (no SELECT) or there is an error
   if (mysqli_errno($link) > 0) {
    $saved_errors[$thread_id] = mysqli_errno($link);
    printf("'%s' caused %d\n", $links[$thread_id]['query'],     mysqli_errno($link));
   }
  }
 }
} while (true);
?>

以上例程会输出:

proxy::reapQuery(array (
  0 => NULL,
))
proxy::reapQuery returns true
array(1) {
  ["one dot one"]=>
  string(3) "1.1"
}
proxy::reapQuery(array (
  0 => NULL,
))
proxy::reapQuery returns true
array(2) {
  ["one"]=>
  string(1) "1"
  ["_sleep"]=>
  string(1) "0"
}

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_real_async_query

MysqlndUhConnection::refreshServer

Flush or reset tables and caches

说明

public bool MysqlndUhConnection::refreshServer ( mysqlnd_connection $connection , <span class="type">int $options )

Flush or reset tables and caches.

Warning

本函数还未编写文档,仅有参数列表。

参数

connection
Mysqlnd connection handle. Do not modify!

options
What to refresh.

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 <span class="function">MysqlndUhConnection::refreshServer example

<?php
class proxy extends MysqlndUhConnection {
 public function refreshServer($res, $option) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::refreshServer($res, $option);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());
$mysqli = new mysqli("localhost", "root", "", "test");
mysqli_refresh($mysqli, 1);
?>

以上例程会输出:

proxy::refreshServer(array (
  0 => NULL,
  1 => 1,
))
proxy::refreshServer returns false

参见

  • mysqlnd_uh_set_connection_proxy

MysqlndUhConnection::restartPSession

Restart a persistent mysqlnd connection

说明

public bool MysqlndUhConnection::restartPSession ( mysqlnd_connection $connection )

Restart a persistent mysqlnd connection.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 <span class="function">MysqlndUhConnection::restartPSession example

<?php
class proxy extends MysqlndUhConnection {
 public function ping($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::ping($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->ping();
?>

以上例程会输出:

proxy::restartPSession(array (
  0 => NULL,
))
proxy::restartPSession returns true

参见

  • mysqlnd_uh_set_connection_proxy

MysqlndUhConnection::selectDb

Selects the default database for database queries

说明

public bool MysqlndUhConnection::selectDb ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">string $database )

Selects the default database for database queries.

参数

connection
Mysqlnd connection handle. Do not modify!

database
The database name.

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 MysqlndUhConnection::selectDb example

<?php
class proxy extends MysqlndUhConnection {
 public function selectDb($res, $database) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::selectDb($res, $database);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());
$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->select_db("mysql");
?>

以上例程会输出:

proxy::selectDb(array (
  0 => NULL,
  1 => 'mysql',
))
proxy::selectDb returns true

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_select_db
  • mysql_select_db

MysqlndUhConnection::sendClose

Sends a close command to MySQL

说明

public bool MysqlndUhConnection::sendClose ( <span class="methodparam">mysqlnd_connection $connection )

Sends a close command to MySQL.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 MysqlndUhConnection::sendClose example

<?php
class proxy extends MysqlndUhConnection {
 public function sendClose($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::sendClose($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());
$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->close();
?>

以上例程会输出:

proxy::sendClose(array (
  0 => NULL,
))
proxy::sendClose returns true
proxy::sendClose(array (
  0 => NULL,
))
proxy::sendClose returns true

参见

  • mysqlnd_uh_set_connection_proxy

MysqlndUhConnection::sendQuery

Sends a query to MySQL

说明

public bool MysqlndUhConnection::sendQuery ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">string $query )

Sends a query to MySQL.

参数

connection
Mysqlnd connection handle. Do not modify!

query
The query string.

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 MysqlndUhConnection::sendQuery example

<?php
class proxy extends MysqlndUhConnection {
 public function sendQuery($res, $query) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::sendQuery($res, $query);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());
$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->query("SELECT 1");
?>

以上例程会输出:

proxy::sendQuery(array (
  0 => NULL,
  1 => 'SELECT 1',
))
proxy::sendQuery returns true

参见

  • mysqlnd_uh_set_connection_proxy

MysqlndUhConnection::serverDumpDebugInformation

Dump debugging information into the log for the MySQL server

说明

public bool <span class="methodname">MysqlndUhConnection::serverDumpDebugInformation ( <span class="type">mysqlnd_connection $connection )

Dump debugging information into the log for the MySQL server.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 <span class="function">MysqlndUhConnection::serverDumpDebugInformation example

<?php
class proxy extends MysqlndUhConnection {
 public function serverDumpDebugInformation($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::serverDumpDebugInformation($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());
$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->dump_debug_info();
?>

以上例程会输出:

proxy::serverDumpDebugInformation(array (
  0 => NULL,
))
proxy::serverDumpDebugInformation returns true

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_dump_debug_info

MysqlndUhConnection::setAutocommit

Turns on or off auto-committing database modifications

说明

public bool MysqlndUhConnection::setAutocommit ( mysqlnd_connection $connection , <span class="type">int $mode )

Turns on or off auto-committing database modifications

参数

connection
Mysqlnd connection handle. Do not modify!

mode
Whether to turn on auto-commit or not.

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 <span class="function">MysqlndUhConnection::setAutocommit example

<?php
class proxy extends MysqlndUhConnection {
 public function setAutocommit($res, $mode) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::setAutocommit($res, $mode);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());
$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->autocommit(false);
$mysqli->autocommit(true);
?>

以上例程会输出:

proxy::setAutocommit(array (
  0 => NULL,
  1 => 0,
))
proxy::setAutocommit returns true
proxy::setAutocommit(array (
  0 => NULL,
  1 => 1,
))
proxy::setAutocommit returns true

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_autocommit

MysqlndUhConnection::setCharset

Sets the default client character set

说明

public bool MysqlndUhConnection::setCharset ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">string $charset )

Sets the default client character set.

参数

connection
Mysqlnd connection handle. Do not modify!

charset
The charset to be set as default.

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 MysqlndUhConnection::setCharset example

<?php
class proxy extends MysqlndUhConnection {
 public function setCharset($res, $charset) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::setCharset($res, $charset);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());
$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->set_charset("latin1");
?>

以上例程会输出:

proxy::setCharset(array (
  0 => NULL,
  1 => 'latin1',
))
proxy::setCharset returns true

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_set_charset

MysqlndUhConnection::setClientOption

Sets a client option

说明

public bool MysqlndUhConnection::setClientOption ( mysqlnd_connection $connection , <span class="type">int $option , <span class="methodparam">int $value )

Sets a client option.

参数

connection
Mysqlnd connection handle. Do not modify!

option
The option to be set.

value
Optional option value, if required.

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 <span class="function">MysqlndUhConnection::setClientOption example

<?php
function client_option_to_string($option) {
 static $mapping = array(
  MYSQLND_UH_MYSQLND_OPTION_OPT_CONNECT_TIMEOUT => "MYSQLND_UH_MYSQLND_OPTION_OPT_CONNECT_TIMEOUT",
  MYSQLND_UH_MYSQLND_OPTION_OPT_COMPRESS => "MYSQLND_UH_MYSQLND_OPTION_OPT_COMPRESS",
  MYSQLND_UH_MYSQLND_OPTION_OPT_NAMED_PIPE => "MYSQLND_UH_MYSQLND_OPTION_OPT_NAMED_PIPE",
  MYSQLND_UH_MYSQLND_OPTION_INIT_COMMAND => "MYSQLND_UH_MYSQLND_OPTION_INIT_COMMAND",
  MYSQLND_UH_MYSQLND_READ_DEFAULT_FILE => "MYSQLND_UH_MYSQLND_READ_DEFAULT_FILE",
  MYSQLND_UH_MYSQLND_READ_DEFAULT_GROUP => "MYSQLND_UH_MYSQLND_READ_DEFAULT_GROUP",
  MYSQLND_UH_MYSQLND_SET_CHARSET_DIR => "MYSQLND_UH_MYSQLND_SET_CHARSET_DIR",
  MYSQLND_UH_MYSQLND_SET_CHARSET_NAME => "MYSQLND_UH_MYSQLND_SET_CHARSET_NAME",
  MYSQLND_UH_MYSQLND_OPT_LOCAL_INFILE => "MYSQLND_UH_MYSQLND_OPT_LOCAL_INFILE",
  MYSQLND_UH_MYSQLND_OPT_PROTOCOL => "MYSQLND_UH_MYSQLND_OPT_PROTOCOL",
  MYSQLND_UH_MYSQLND_SHARED_MEMORY_BASE_NAME => "MYSQLND_UH_MYSQLND_SHARED_MEMORY_BASE_NAME",
  MYSQLND_UH_MYSQLND_OPT_READ_TIMEOUT => "MYSQLND_UH_MYSQLND_OPT_READ_TIMEOUT",
  MYSQLND_UH_MYSQLND_OPT_WRITE_TIMEOUT => "MYSQLND_UH_MYSQLND_OPT_WRITE_TIMEOUT",
  MYSQLND_UH_MYSQLND_OPT_USE_RESULT => "MYSQLND_UH_MYSQLND_OPT_USE_RESULT",
  MYSQLND_UH_MYSQLND_OPT_USE_REMOTE_CONNECTION => "MYSQLND_UH_MYSQLND_OPT_USE_REMOTE_CONNECTION",
  MYSQLND_UH_MYSQLND_OPT_USE_EMBEDDED_CONNECTION => "MYSQLND_UH_MYSQLND_OPT_USE_EMBEDDED_CONNECTION",
  MYSQLND_UH_MYSQLND_OPT_GUESS_CONNECTION => "MYSQLND_UH_MYSQLND_OPT_GUESS_CONNECTION",
  MYSQLND_UH_MYSQLND_SET_CLIENT_IP => "MYSQLND_UH_MYSQLND_SET_CLIENT_IP",
  MYSQLND_UH_MYSQLND_SECURE_AUTH => "MYSQLND_UH_MYSQLND_SECURE_AUTH",
  MYSQLND_UH_MYSQLND_REPORT_DATA_TRUNCATION => "MYSQLND_UH_MYSQLND_REPORT_DATA_TRUNCATION",
  MYSQLND_UH_MYSQLND_OPT_RECONNECT => "MYSQLND_UH_MYSQLND_OPT_RECONNECT",
  MYSQLND_UH_MYSQLND_OPT_SSL_VERIFY_SERVER_CERT => "MYSQLND_UH_MYSQLND_OPT_SSL_VERIFY_SERVER_CERT",
  MYSQLND_UH_MYSQLND_OPT_NET_CMD_BUFFER_SIZE => "MYSQLND_UH_MYSQLND_OPT_NET_CMD_BUFFER_SIZE",
  MYSQLND_UH_MYSQLND_OPT_NET_READ_BUFFER_SIZE => "MYSQLND_UH_MYSQLND_OPT_NET_READ_BUFFER_SIZE",
  MYSQLND_UH_MYSQLND_OPT_SSL_KEY => "MYSQLND_UH_MYSQLND_OPT_SSL_KEY",
  MYSQLND_UH_MYSQLND_OPT_SSL_CERT => "MYSQLND_UH_MYSQLND_OPT_SSL_CERT",
  MYSQLND_UH_MYSQLND_OPT_SSL_CA => "MYSQLND_UH_MYSQLND_OPT_SSL_CA",
  MYSQLND_UH_MYSQLND_OPT_SSL_CAPATH => "MYSQLND_UH_MYSQLND_OPT_SSL_CAPATH",
  MYSQLND_UH_MYSQLND_OPT_SSL_CIPHER => "MYSQLND_UH_MYSQLND_OPT_SSL_CIPHER",
  MYSQLND_UH_MYSQLND_OPT_SSL_PASSPHRASE => "MYSQLND_UH_MYSQLND_OPT_SSL_PASSPHRASE",
  MYSQLND_UH_SERVER_OPTION_PLUGIN_DIR => "MYSQLND_UH_SERVER_OPTION_PLUGIN_DIR",
  MYSQLND_UH_SERVER_OPTION_DEFAULT_AUTH => "MYSQLND_UH_SERVER_OPTION_DEFAULT_AUTH",
  MYSQLND_UH_SERVER_OPTION_SET_CLIENT_IP => "MYSQLND_UH_SERVER_OPTION_SET_CLIENT_IP"
 );
 if (version_compare(PHP_VERSION, '5.3.99-dev', '>')) {
  $mapping[MYSQLND_UH_MYSQLND_OPT_MAX_ALLOWED_PACKET] = "MYSQLND_UH_MYSQLND_OPT_MAX_ALLOWED_PACKET";
  $mapping[MYSQLND_UH_MYSQLND_OPT_AUTH_PROTOCOL] = "MYSQLND_UH_MYSQLND_OPT_AUTH_PROTOCOL";
 }
 if (defined("MYSQLND_UH_MYSQLND_OPT_INT_AND_FLOAT_NATIVE")) {
  /* special mysqlnd build */
  $mapping["MYSQLND_UH_MYSQLND_OPT_INT_AND_FLOAT_NATIVE"] = "MYSQLND_UH_MYSQLND_OPT_INT_AND_FLOAT_NATIVE";
 }
 return (isset($mapping[$option])) ? $mapping[$option] : 'unknown';
}

class proxy extends MysqlndUhConnection {
 public function setClientOption($res, $option, $value) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  printf("Option '%s' set to %s\n", client_option_to_string($option), var_export($value, true));
  $ret = parent::setClientOption($res, $option, $value);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());
$mysqli = new mysqli("localhost", "root", "", "test");
?>

以上例程会输出:

proxy::setClientOption(array (
  0 => NULL,
  1 => 210,
  2 => 3221225472,
))
Option 'MYSQLND_UH_MYSQLND_OPT_MAX_ALLOWED_PACKET' set to 3221225472
proxy::setClientOption returns true
proxy::setClientOption(array (
  0 => NULL,
  1 => 211,
  2 => 'mysql_native_password',
))
Option 'MYSQLND_UH_MYSQLND_OPT_AUTH_PROTOCOL' set to 'mysql_native_password'
proxy::setClientOption returns true
proxy::setClientOption(array (
  0 => NULL,
  1 => 8,
  2 => 1,
))
Option 'MYSQLND_UH_MYSQLND_OPT_LOCAL_INFILE' set to 1
proxy::setClientOption returns true

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_real_connect
  • mysqli_options

MysqlndUhConnection::setServerOption

Sets a server option

说明

public void MysqlndUhConnection::setServerOption ( mysqlnd_connection $connection , <span class="type">int $option )

Sets a server option.

参数

connection
Mysqlnd connection handle. Do not modify!

option
The option to be set.

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 <span class="function">MysqlndUhConnection::setServerOption example

<?php
function server_option_to_string($option) {
 $ret = 'unknown';
 switch ($option) {
  case MYSQLND_UH_SERVER_OPTION_MULTI_STATEMENTS_ON:
   $ret = 'MYSQLND_UH_SERVER_OPTION_MULTI_STATEMENTS_ON';
   break;
  case MYSQLND_UH_SERVER_OPTION_MULTI_STATEMENTS_OFF:
   $ret = 'MYSQLND_UH_SERVER_OPTION_MULTI_STATEMENTS_ON';
   break;
 }
 return $ret;
}

class proxy extends MysqlndUhConnection {
 public function setServerOption($res, $option) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  printf("Option '%s' set\n", server_option_to_string($option));
  $ret = parent::setServerOption($res, $option);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());
$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->multi_query("SELECT 1; SELECT 2");
?>

以上例程会输出:

proxy::setServerOption(array (
  0 => NULL,
  1 => 0,
))
Option 'MYSQLND_UH_SERVER_OPTION_MULTI_STATEMENTS_ON' set
proxy::setServerOption returns true

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_real_connect
  • mysqli_options
  • mysqli_multi_query

MysqlndUhConnection::shutdownServer

The shutdownServer purpose

说明

public void MysqlndUhConnection::shutdownServer ( string $MYSQLND_UH_RES_MYSQLND_NAME , <span class="type">string $level )

Warning

本函数还未编写文档,仅有参数列表。

参数

MYSQLND_UH_RES_MYSQLND_NAME

level

返回值

MysqlndUhConnection::simpleCommand

Sends a basic COM_* command

说明

public bool MysqlndUhConnection::simpleCommand ( mysqlnd_connection $connection , <span class="type">int $command , <span class="methodparam">string $arg , int $ok_packet , <span class="type">bool $silent , <span class="methodparam">bool $ignore_upsert_status )

Sends a basic COM_* command to MySQL.

参数

connection
Mysqlnd connection handle. Do not modify!

command
The COM command to be send.

arg
Optional COM command arguments.

ok_packet
The OK packet type.

silent
Whether mysqlnd may emit errors.

ignore_upsert_status
Whether to ignore UPDATE/INSERT status.

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 <span class="function">MysqlndUhConnection::simpleCommand example

<?php
function server_cmd_2_string($command) {
 $mapping = array(
  MYSQLND_UH_MYSQLND_COM_SLEEP => "MYSQLND_UH_MYSQLND_COM_SLEEP",
  MYSQLND_UH_MYSQLND_COM_QUIT => "MYSQLND_UH_MYSQLND_COM_QUIT",
  MYSQLND_UH_MYSQLND_COM_INIT_DB => "MYSQLND_UH_MYSQLND_COM_INIT_DB",
  MYSQLND_UH_MYSQLND_COM_QUERY => "MYSQLND_UH_MYSQLND_COM_QUERY",
  MYSQLND_UH_MYSQLND_COM_FIELD_LIST => "MYSQLND_UH_MYSQLND_COM_FIELD_LIST",
  MYSQLND_UH_MYSQLND_COM_CREATE_DB => "MYSQLND_UH_MYSQLND_COM_CREATE_DB",
  MYSQLND_UH_MYSQLND_COM_DROP_DB => "MYSQLND_UH_MYSQLND_COM_DROP_DB",
  MYSQLND_UH_MYSQLND_COM_REFRESH => "MYSQLND_UH_MYSQLND_COM_REFRESH",
  MYSQLND_UH_MYSQLND_COM_SHUTDOWN => "MYSQLND_UH_MYSQLND_COM_SHUTDOWN",
  MYSQLND_UH_MYSQLND_COM_STATISTICS => "MYSQLND_UH_MYSQLND_COM_STATISTICS",
  MYSQLND_UH_MYSQLND_COM_PROCESS_INFO => "MYSQLND_UH_MYSQLND_COM_PROCESS_INFO",
  MYSQLND_UH_MYSQLND_COM_CONNECT => "MYSQLND_UH_MYSQLND_COM_CONNECT",
  MYSQLND_UH_MYSQLND_COM_PROCESS_KILL => "MYSQLND_UH_MYSQLND_COM_PROCESS_KILL",
  MYSQLND_UH_MYSQLND_COM_DEBUG => "MYSQLND_UH_MYSQLND_COM_DEBUG",
  MYSQLND_UH_MYSQLND_COM_PING => "MYSQLND_UH_MYSQLND_COM_PING",
  MYSQLND_UH_MYSQLND_COM_TIME => "MYSQLND_UH_MYSQLND_COM_TIME",
  MYSQLND_UH_MYSQLND_COM_DELAYED_INSERT => "MYSQLND_UH_MYSQLND_COM_DELAYED_INSERT",
  MYSQLND_UH_MYSQLND_COM_CHANGE_USER => "MYSQLND_UH_MYSQLND_COM_CHANGE_USER",
  MYSQLND_UH_MYSQLND_COM_BINLOG_DUMP => "MYSQLND_UH_MYSQLND_COM_BINLOG_DUMP",
  MYSQLND_UH_MYSQLND_COM_TABLE_DUMP => "MYSQLND_UH_MYSQLND_COM_TABLE_DUMP",
  MYSQLND_UH_MYSQLND_COM_CONNECT_OUT => "MYSQLND_UH_MYSQLND_COM_CONNECT_OUT",
  MYSQLND_UH_MYSQLND_COM_REGISTER_SLAVED => "MYSQLND_UH_MYSQLND_COM_REGISTER_SLAVED",
  MYSQLND_UH_MYSQLND_COM_STMT_PREPARE => "MYSQLND_UH_MYSQLND_COM_STMT_PREPARE",
  MYSQLND_UH_MYSQLND_COM_STMT_EXECUTE => "MYSQLND_UH_MYSQLND_COM_STMT_EXECUTE",
  MYSQLND_UH_MYSQLND_COM_STMT_SEND_LONG_DATA => "MYSQLND_UH_MYSQLND_COM_STMT_SEND_LONG_DATA",
  MYSQLND_UH_MYSQLND_COM_STMT_CLOSE => "MYSQLND_UH_MYSQLND_COM_STMT_CLOSE",
  MYSQLND_UH_MYSQLND_COM_STMT_RESET => "MYSQLND_UH_MYSQLND_COM_STMT_RESET",
  MYSQLND_UH_MYSQLND_COM_SET_OPTION => "MYSQLND_UH_MYSQLND_COM_SET_OPTION",
  MYSQLND_UH_MYSQLND_COM_STMT_FETCH => "MYSQLND_UH_MYSQLND_COM_STMT_FETCH",
  MYSQLND_UH_MYSQLND_COM_DAEMON => "MYSQLND_UH_MYSQLND_COM_DAEMON",
  MYSQLND_UH_MYSQLND_COM_END => "MYSQLND_UH_MYSQLND_COM_END",
 );
 return (isset($mapping[$command])) ? $mapping[$command] : 'unknown';
}

function ok_packet_2_string($ok_packet) {
 $mapping = array(
  MYSQLND_UH_MYSQLND_PROT_GREET_PACKET => "MYSQLND_UH_MYSQLND_PROT_GREET_PACKET",
  MYSQLND_UH_MYSQLND_PROT_AUTH_PACKET => "MYSQLND_UH_MYSQLND_PROT_AUTH_PACKET",
  MYSQLND_UH_MYSQLND_PROT_OK_PACKET => "MYSQLND_UH_MYSQLND_PROT_OK_PACKET",
  MYSQLND_UH_MYSQLND_PROT_EOF_PACKET => "MYSQLND_UH_MYSQLND_PROT_EOF_PACKET",
  MYSQLND_UH_MYSQLND_PROT_CMD_PACKET => "MYSQLND_UH_MYSQLND_PROT_CMD_PACKET",
  MYSQLND_UH_MYSQLND_PROT_RSET_HEADER_PACKET => "MYSQLND_UH_MYSQLND_PROT_RSET_HEADER_PACKET",
  MYSQLND_UH_MYSQLND_PROT_RSET_FLD_PACKET => "MYSQLND_UH_MYSQLND_PROT_RSET_FLD_PACKET",
  MYSQLND_UH_MYSQLND_PROT_ROW_PACKET => "MYSQLND_UH_MYSQLND_PROT_ROW_PACKET",
  MYSQLND_UH_MYSQLND_PROT_STATS_PACKET => "MYSQLND_UH_MYSQLND_PROT_STATS_PACKET",
  MYSQLND_UH_MYSQLND_PREPARE_RESP_PACKET => "MYSQLND_UH_MYSQLND_PREPARE_RESP_PACKET",
  MYSQLND_UH_MYSQLND_CHG_USER_RESP_PACKET => "MYSQLND_UH_MYSQLND_CHG_USER_RESP_PACKET",
  MYSQLND_UH_MYSQLND_PROT_LAST => "MYSQLND_UH_MYSQLND_PROT_LAST",
 );
 return (isset($mapping[$ok_packet])) ? $mapping[$ok_packet] : 'unknown';
}

class proxy extends MysqlndUhConnection {
 public function simpleCommand($conn, $command, $arg, $ok_packet, $silent, $ignore_upsert_status) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  printf("Command '%s'\n", server_cmd_2_string($command));
  printf("OK packet '%s'\n",  ok_packet_2_string($ok_packet));
  $ret = parent::simpleCommand($conn, $command, $arg, $ok_packet, $silent, $ignore_upsert_status);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());
$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->query("SELECT 1");
?>

以上例程会输出:

proxy::simpleCommand(array (
  0 => NULL,
  1 => 3,
  2 => 'SELECT 1',
  3 => 13,
  4 => false,
  5 => false,
))
Command 'MYSQLND_UH_MYSQLND_COM_QUERY'
OK packet 'MYSQLND_UH_MYSQLND_PROT_LAST'
proxy::simpleCommand returns true
:)proxy::simpleCommand(array (
  0 => NULL,
  1 => 1,
  2 => '',
  3 => 13,
  4 => true,
  5 => true,
))
Command 'MYSQLND_UH_MYSQLND_COM_QUIT'
OK packet 'MYSQLND_UH_MYSQLND_PROT_LAST'
proxy::simpleCommand returns true

参见

  • mysqlnd_uh_set_connection_proxy

MysqlndUhConnection::simpleCommandHandleResponse

Process a response for a basic COM_* command send to the client

说明

public bool <span class="methodname">MysqlndUhConnection::simpleCommandHandleResponse ( <span class="type">mysqlnd_connection $connection , <span class="methodparam">int $ok_packet , bool $silent , <span class="type">int $command , <span class="methodparam">bool $ignore_upsert_status )

Process a response for a basic COM_* command send to the client.

参数

connection
Mysqlnd connection handle. Do not modify!

ok_packet
The OK packet type.

silent
Whether mysqlnd may emit errors.

command
The COM command to process results from.

ignore_upsert_status
Whether to ignore UPDATE/INSERT status.

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 <span class="function">MysqlndUhConnection::simpleCommandHandleResponse example

<?php
function server_cmd_2_string($command) {
 $mapping = array(
  MYSQLND_UH_MYSQLND_COM_SLEEP => "MYSQLND_UH_MYSQLND_COM_SLEEP",
  MYSQLND_UH_MYSQLND_COM_QUIT => "MYSQLND_UH_MYSQLND_COM_QUIT",
  MYSQLND_UH_MYSQLND_COM_INIT_DB => "MYSQLND_UH_MYSQLND_COM_INIT_DB",
  MYSQLND_UH_MYSQLND_COM_QUERY => "MYSQLND_UH_MYSQLND_COM_QUERY",
  MYSQLND_UH_MYSQLND_COM_FIELD_LIST => "MYSQLND_UH_MYSQLND_COM_FIELD_LIST",
  MYSQLND_UH_MYSQLND_COM_CREATE_DB => "MYSQLND_UH_MYSQLND_COM_CREATE_DB",
  MYSQLND_UH_MYSQLND_COM_DROP_DB => "MYSQLND_UH_MYSQLND_COM_DROP_DB",
  MYSQLND_UH_MYSQLND_COM_REFRESH => "MYSQLND_UH_MYSQLND_COM_REFRESH",
  MYSQLND_UH_MYSQLND_COM_SHUTDOWN => "MYSQLND_UH_MYSQLND_COM_SHUTDOWN",
  MYSQLND_UH_MYSQLND_COM_STATISTICS => "MYSQLND_UH_MYSQLND_COM_STATISTICS",
  MYSQLND_UH_MYSQLND_COM_PROCESS_INFO => "MYSQLND_UH_MYSQLND_COM_PROCESS_INFO",
  MYSQLND_UH_MYSQLND_COM_CONNECT => "MYSQLND_UH_MYSQLND_COM_CONNECT",
  MYSQLND_UH_MYSQLND_COM_PROCESS_KILL => "MYSQLND_UH_MYSQLND_COM_PROCESS_KILL",
  MYSQLND_UH_MYSQLND_COM_DEBUG => "MYSQLND_UH_MYSQLND_COM_DEBUG",
  MYSQLND_UH_MYSQLND_COM_PING => "MYSQLND_UH_MYSQLND_COM_PING",
  MYSQLND_UH_MYSQLND_COM_TIME => "MYSQLND_UH_MYSQLND_COM_TIME",
  MYSQLND_UH_MYSQLND_COM_DELAYED_INSERT => "MYSQLND_UH_MYSQLND_COM_DELAYED_INSERT",
  MYSQLND_UH_MYSQLND_COM_CHANGE_USER => "MYSQLND_UH_MYSQLND_COM_CHANGE_USER",
  MYSQLND_UH_MYSQLND_COM_BINLOG_DUMP => "MYSQLND_UH_MYSQLND_COM_BINLOG_DUMP",
  MYSQLND_UH_MYSQLND_COM_TABLE_DUMP => "MYSQLND_UH_MYSQLND_COM_TABLE_DUMP",
  MYSQLND_UH_MYSQLND_COM_CONNECT_OUT => "MYSQLND_UH_MYSQLND_COM_CONNECT_OUT",
  MYSQLND_UH_MYSQLND_COM_REGISTER_SLAVED => "MYSQLND_UH_MYSQLND_COM_REGISTER_SLAVED",
  MYSQLND_UH_MYSQLND_COM_STMT_PREPARE => "MYSQLND_UH_MYSQLND_COM_STMT_PREPARE",
  MYSQLND_UH_MYSQLND_COM_STMT_EXECUTE => "MYSQLND_UH_MYSQLND_COM_STMT_EXECUTE",
  MYSQLND_UH_MYSQLND_COM_STMT_SEND_LONG_DATA => "MYSQLND_UH_MYSQLND_COM_STMT_SEND_LONG_DATA",
  MYSQLND_UH_MYSQLND_COM_STMT_CLOSE => "MYSQLND_UH_MYSQLND_COM_STMT_CLOSE",
  MYSQLND_UH_MYSQLND_COM_STMT_RESET => "MYSQLND_UH_MYSQLND_COM_STMT_RESET",
  MYSQLND_UH_MYSQLND_COM_SET_OPTION => "MYSQLND_UH_MYSQLND_COM_SET_OPTION",
  MYSQLND_UH_MYSQLND_COM_STMT_FETCH => "MYSQLND_UH_MYSQLND_COM_STMT_FETCH",
  MYSQLND_UH_MYSQLND_COM_DAEMON => "MYSQLND_UH_MYSQLND_COM_DAEMON",
  MYSQLND_UH_MYSQLND_COM_END => "MYSQLND_UH_MYSQLND_COM_END",
 );
 return (isset($mapping[$command])) ? $mapping[$command] : 'unknown';
}

function ok_packet_2_string($ok_packet) {
 $mapping = array(
  MYSQLND_UH_MYSQLND_PROT_GREET_PACKET => "MYSQLND_UH_MYSQLND_PROT_GREET_PACKET",
  MYSQLND_UH_MYSQLND_PROT_AUTH_PACKET => "MYSQLND_UH_MYSQLND_PROT_AUTH_PACKET",
  MYSQLND_UH_MYSQLND_PROT_OK_PACKET => "MYSQLND_UH_MYSQLND_PROT_OK_PACKET",
  MYSQLND_UH_MYSQLND_PROT_EOF_PACKET => "MYSQLND_UH_MYSQLND_PROT_EOF_PACKET",
  MYSQLND_UH_MYSQLND_PROT_CMD_PACKET => "MYSQLND_UH_MYSQLND_PROT_CMD_PACKET",
  MYSQLND_UH_MYSQLND_PROT_RSET_HEADER_PACKET => "MYSQLND_UH_MYSQLND_PROT_RSET_HEADER_PACKET",
  MYSQLND_UH_MYSQLND_PROT_RSET_FLD_PACKET => "MYSQLND_UH_MYSQLND_PROT_RSET_FLD_PACKET",
  MYSQLND_UH_MYSQLND_PROT_ROW_PACKET => "MYSQLND_UH_MYSQLND_PROT_ROW_PACKET",
  MYSQLND_UH_MYSQLND_PROT_STATS_PACKET => "MYSQLND_UH_MYSQLND_PROT_STATS_PACKET",
  MYSQLND_UH_MYSQLND_PREPARE_RESP_PACKET => "MYSQLND_UH_MYSQLND_PREPARE_RESP_PACKET",
  MYSQLND_UH_MYSQLND_CHG_USER_RESP_PACKET => "MYSQLND_UH_MYSQLND_CHG_USER_RESP_PACKET",
  MYSQLND_UH_MYSQLND_PROT_LAST => "MYSQLND_UH_MYSQLND_PROT_LAST",
 );
 return (isset($mapping[$ok_packet])) ? $mapping[$ok_packet] : 'unknown';
}

class proxy extends MysqlndUhConnection {
 public function simpleCommandHandleResponse($conn, $ok_packet, $silent, $command, $ignore_upsert_status) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  printf("Command '%s'\n", server_cmd_2_string($command));
  printf("OK packet '%s'\n",  ok_packet_2_string($ok_packet));
  $ret = parent::simpleCommandHandleResponse($conn, $ok_packet, $silent, $command, $ignore_upsert_status);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());
$mysql = mysql_connect("localhost", "root", "");
mysql_query("SELECT 1 FROM DUAL", $mysql);
?>

以上例程会输出:

proxy::simpleCommandHandleResponse(array (
  0 => NULL,
  1 => 5,
  2 => false,
  3 => 27,
  4 => true,
))
Command 'MYSQLND_UH_MYSQLND_COM_SET_OPTION'
OK packet 'MYSQLND_UH_MYSQLND_PROT_EOF_PACKET'
proxy::simpleCommandHandleResponse returns true

参见

  • mysqlnd_uh_set_connection_proxy

MysqlndUhConnection::sslSet

Used for establishing secure connections using SSL

说明

public bool MysqlndUhConnection::sslSet ( <span class="methodparam">mysqlnd_connection $connection , <span class="type">string $key , <span class="methodparam">string $cert , string $ca , string $capath , <span class="type">string $cipher )

Used for establishing secure connections using SSL.

参数

connection
Mysqlnd connection handle. Do not modify!

key
The path name to the key file.

cert
The path name to the certificate file.

ca
The path name to the certificate authority file.

capath
The pathname to a directory that contains trusted SSL CA certificates in PEM format.

cipher
A list of allowable ciphers to use for SSL encryption.

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 MysqlndUhConnection::sslSet example

<?php
class proxy extends MysqlndUhConnection {
 public function sslSet($conn, $key, $cert, $ca, $capath, $cipher) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::sslSet($conn, $key, $cert, $ca, $capath, $cipher);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());
$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->ssl_set("key", "cert", "ca", "capath", "cipher");
?>

以上例程会输出:

proxy::sslSet(array (
  0 => NULL,
  1 => 'key',
  2 => 'cert',
  3 => 'ca',
  4 => 'capath',
  5 => 'cipher',
))
proxy::sslSet returns true

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_ssl_set

MysqlndUhConnection::stmtInit

Initializes a statement and returns a resource for use with mysqli_statement::prepare

说明

public resource MysqlndUhConnection::stmtInit ( <span class="methodparam">mysqlnd_connection $connection )

Initializes a statement and returns a resource for use with mysqli_statement::prepare.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Resource of type Mysqlnd Prepared Statement (internal only - you must not modify it!). The documentation may also refer to such resources using the alias name mysqlnd_prepared_statement.

范例

示例 #1 MysqlndUhConnection::stmtInit example

<?php
class proxy extends MysqlndUhConnection {
 public function stmtInit($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  var_dump($res);
  $ret = parent::stmtInit($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  var_dump($ret);
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());
$mysqli = new mysqli("localhost", "root", "", "test");
$stmt = $mysqli->prepare("SELECT 1 AS _one FROM DUAL");
$stmt->execute();
$one = NULL;
$stmt->bind_result($one);
$stmt->fetch();
var_dump($one);
?>

以上例程会输出:

proxy::stmtInit(array (
  0 => NULL,
))
resource(19) of type (Mysqlnd Connection)
proxy::stmtInit returns NULL
resource(246) of type (Mysqlnd Prepared Statement (internal only - you must not modify it!))
int(1)

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_stmt_init

MysqlndUhConnection::storeResult

Transfers a result set from the last query

说明

public resource MysqlndUhConnection::storeResult ( <span class="methodparam">mysqlnd_connection $connection )

Transfers a result set from the last query.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Resource of type Mysqlnd Resultset (internal only - you must not modify it!). The documentation may also refer to such resources using the alias name mysqlnd_resultset.

范例

示例 #1 <span class="function">MysqlndUhConnection::storeResult example

<?php
class proxy extends MysqlndUhConnection {
 public function storeResult($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::storeResult($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  var_dump($ret);
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$res = $mysqli->query("SELECT 'Also called buffered result' AS _msg FROM DUAL");
var_dump($res->fetch_assoc());

$mysqli->real_query("SELECT 'Good morning!' AS _msg FROM DUAL");
$res = $mysqli->store_result();
var_dump($res->fetch_assoc());
?>

以上例程会输出:

proxy::storeResult(array (
  0 => NULL,
))
proxy::storeResult returns NULL
resource(475) of type (Mysqlnd Resultset (internal only - you must not modify it!))
array(1) {
  ["_msg"]=>
  string(27) "Also called buffered result"
}
proxy::storeResult(array (
  0 => NULL,
))
proxy::storeResult returns NULL
resource(730) of type (Mysqlnd Resultset (internal only - you must not modify it!))
array(1) {
  ["_msg"]=>
  string(13) "Good morning!"
}

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_store_result
  • mysqli_real_query

MysqlndUhConnection::txCommit

Commits the current transaction

说明

public bool MysqlndUhConnection::txCommit ( <span class="methodparam">mysqlnd_connection $connection )

Commits the current transaction.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 MysqlndUhConnection::txCommit example

<?php
class proxy extends MysqlndUhConnection {
 public function txCommit($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::txCommit($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->commit();
?>

以上例程会输出:

proxy::txCommit(array (
  0 => NULL,
))
proxy::txCommit returns true

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_commit

MysqlndUhConnection::txRollback

Rolls back current transaction

说明

public bool MysqlndUhConnection::txRollback ( <span class="methodparam">mysqlnd_connection $connection )

Rolls back current transaction.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 MysqlndUhConnection::txRollback example

<?php
class proxy extends MysqlndUhConnection {
 public function txRollback($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::txRollback($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->rollback();
?>

以上例程会输出:

proxy::txRollback(array (
  0 => NULL,
))
proxy::txRollback returns true

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_commit

MysqlndUhConnection::useResult

Initiate a result set retrieval

说明

public resource MysqlndUhConnection::useResult ( <span class="methodparam">mysqlnd_connection $connection )

Initiate a result set retrieval.

参数

connection
Mysqlnd connection handle. Do not modify!

返回值

Resource of type Mysqlnd Resultset (internal only - you must not modify it!). The documentation may also refer to such resources using the alias name mysqlnd_resultset.

范例

示例 #1 MysqlndUhConnection::useResult example

<?php
class proxy extends MysqlndUhConnection {
 public function useResult($res) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $ret = parent::useResult($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  var_dump($ret);
  return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->real_query("SELECT 'Good morning!' AS _msg FROM DUAL");
$res = $mysqli->use_result();
var_dump($res->fetch_assoc());
?>

以上例程会输出:

proxy::useResult(array (
  0 => NULL,
))
proxy::useResult returns NULL
resource(425) of type (Mysqlnd Resultset (internal only - you must not modify it!))
array(1) {
  ["_msg"]=>
  string(13) "Good morning!"
}

参见

  • mysqlnd_uh_set_connection_proxy
  • mysqli_use_result
  • mysqli_real_query

简介

类摘要

MysqlndUhPreparedStatement

class MysqlndUhPreparedStatement {

/* 方法 */

public <span class="methodname">__construct ( <span class="methodparam">void )

public bool execute ( <span class="methodparam"><span class="type">mysqlnd_prepared_statement $statement )

public bool prepare ( <span class="methodparam"><span class="type">mysqlnd_prepared_statement $statement , string $query )

}

MysqlndUhPreparedStatement::__construct

The __construct purpose

说明

public <span class="methodname">MysqlndUhPreparedStatement::__construct ( void )

Warning

本函数还未编写文档,仅有参数列表。

参数

此函数没有参数。

返回值

MysqlndUhPreparedStatement::execute

Executes a prepared Query

说明

public bool MysqlndUhPreparedStatement::execute ( <span class="type">mysqlnd_prepared_statement $statement )

Executes a prepared Query.

参数

statement
Mysqlnd prepared statement handle. Do not modify! Resource of type Mysqlnd Prepared Statement (internal only - you must not modify it!).

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 <span class="function">MysqlndUhPreparedStatement::execute example

<?php
class stmt_proxy extends MysqlndUhPreparedStatement {
 public function execute($res) {
  printf("%s(", __METHOD__);
  var_dump($res);
  printf(")\n");
  $ret = parent::execute($res);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  var_dump($ret);
  return $ret;
 }
}
mysqlnd_uh_set_statement_proxy(new stmt_proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$stmt = $mysqli->prepare("SELECT 'Labskaus' AS _msg FROM DUAL");
$stmt->execute();
$msg = NULL;
$stmt->bind_result($msg);
$stmt->fetch();
var_dump($msg);
?>

以上例程会输出:

stmt_proxy::execute(resource(256) of type (Mysqlnd Prepared Statement (internal only - you must not modify it!))
)
stmt_proxy::execute returns true
bool(true)
string(8) "Labskaus"

参见

  • mysqlnd_uh_set_statement_proxy
  • mysqli_stmt_execute

MysqlndUhPreparedStatement::prepare

Prepare an SQL statement for execution

说明

public bool MysqlndUhPreparedStatement::prepare ( <span class="type">mysqlnd_prepared_statement $statement , string $query )

Prepare an SQL statement for execution.

参数

statement
Mysqlnd prepared statement handle. Do not modify! Resource of type Mysqlnd Prepared Statement (internal only - you must not modify it!).

query
The query to be prepared.

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 <span class="function">MysqlndUhPreparedStatement::prepare example

<?php
class stmt_proxy extends MysqlndUhPreparedStatement {
 public function prepare($res, $query) {
  printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
  $query = "SELECT 'No more you-know-what-I-mean for lunch, please' AS _msg FROM DUAL";
  $ret = parent::prepare($res, $query);
  printf("%s returns %s\n", __METHOD__, var_export($ret, true));
  var_dump($ret);
  return $ret;
 }
}
mysqlnd_uh_set_statement_proxy(new stmt_proxy());

$mysqli = new mysqli("localhost", "root", "", "test");
$stmt = $mysqli->prepare("SELECT 'Labskaus' AS _msg FROM DUAL");
$stmt->execute();
$msg = NULL;
$stmt->bind_result($msg);
$stmt->fetch();
var_dump($msg);
?>

以上例程会输出:

stmt_proxy::prepare(array (
  0 => NULL,
  1 => 'SELECT \'Labskaus\' AS _msg FROM DUAL',
))
stmt_proxy::prepare returns true
bool(true)
string(46) "No more you-know-what-I-mean for lunch, please"

参见

  • mysqlnd_uh_set_statement_proxy
  • mysqli_stmt_prepare
  • mysqli_prepare

mysqlnd_uh_convert_to_mysqlnd

Converts a MySQL connection handle into a mysqlnd connection handle

说明

resource <span class="methodname">mysqlnd_uh_convert_to_mysqlnd ( <span class="methodparam">mysqli &$mysql_connection )

Converts a MySQL connection handle into a mysqlnd connection handle. After conversion you can execute mysqlnd library calls on the connection handle. This can be used to access mysqlnd functionality not made available through user space API calls.

The function can be disabled with mysqlnd_uh.enable. If mysqlnd_uh.enable is set to false the function will not install the proxy and always return true. Additionally, an error of the type E_WARNING may be emitted. The error message may read like PHP Warning: mysqlnd_uh_convert_to_mysqlnd(): (Mysqlnd User Handler) The plugin has been disabled by setting the configuration parameter mysqlnd_uh.enable = false. You are not allowed to call this function [...].

参数

MySQL connection handle
A MySQL connection handle of type mysql, mysqli or PDO_MySQL.

返回值

A mysqlnd connection handle.

更新日志

版本 说明
5.4.0 The mysql_connection parameter can now be of type mysql, PDO_MySQL, or mysqli. Before, only the mysqli type was allowed.

范例

示例 #1 <span class="function">mysqlnd_uh_convert_to_mysqlnd example

<?php
/* PDO user API gives no access to connection thread id */
$mysql_connection = new PDO("mysql:host=localhost;dbname=test", "root", "");

/* Convert PDO MySQL handle to mysqlnd handle */
$mysqlnd = mysqlnd_uh_convert_to_mysqlnd($mysql_connection);

/* Create Proxy to call mysqlnd connection class methods */
$obj = new MySQLndUHConnection();
/* Call mysqlnd_conn::get_thread_id */
var_dump($obj->getThreadId($mysqlnd));

/* Use SQL to fetch connection thread id */
var_dump($mysql_connection->query("SELECT CONNECTION_ID()")->fetchAll());
?>

以上例程会输出:

int(27054)
array(1) {
  [0]=>
  array(2) {
    ["CONNECTION_ID()"]=>
    string(5) "27054"
    [0]=>
    string(5) "27054"
  }
}

参见

mysqlnd_uh_set_connection_proxy

Installs a proxy for mysqlnd connections

说明

bool <span class="methodname">mysqlnd_uh_set_connection_proxy ( <span class="methodparam">MysqlndUhConnection &$connection_proxy [, <span class="type">mysqli &$mysqli_connection ] )

Installs a proxy object to hook mysqlnd's connection objects methods. Once installed, the proxy will be used for all MySQL connections opened with mysqli, mysql or PDO_MYSQL, assuming that the listed extensions are compiled to use the mysqlnd library.

The function can be disabled with mysqlnd_uh.enable. If mysqlnd_uh.enable is set to false the function will not install the proxy and always return true. Additionally, an error of the type E_WARNING may be emitted. The error message may read like PHP Warning: mysqlnd_uh_set_connection_proxy(): (Mysqlnd User Handler) The plugin has been disabled by setting the configuration parameter mysqlnd_uh.enable = false. The proxy has not been installed [...].

参数

connection_proxy
A proxy object of type <span class="classname">MysqlndUhConnection.

mysqli_connection
Object of type mysqli. If given, the proxy will be set for this particular connection only.

返回值

Returns true on success. Otherwise, returns false

范例

示例 #1 <span class="function">mysqlnd_uh_set_connection_proxy example

<?php
$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->query("SELECT 'No proxy installed, yet'");

class proxy extends MysqlndUhConnection {
 public function query($res, $query) {
   printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
   $ret = parent::query($res, $query);
   printf("%s returns %s\n", __METHOD__, var_export($ret, true));
   return $ret;
 }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli->query("SELECT 'mysqlnd rocks!'");

$mysql = mysql_connect("localhost", "root", "", "test");
mysql_query("SELECT 'Ahoy Andrey!'", $mysql);

$pdo = new PDO("mysql:host=localhost;dbname=test", "root", "");
$pdo->query("SELECT 'Moin Johannes!'");
?>

以上例程会输出:

proxy::query(array (
  0 => NULL,
  1 => 'SELECT \'mysqlnd rocks!\'',
))
proxy::query returns true
proxy::query(array (
  0 => NULL,
  1 => 'SELECT \'Ahoy Andrey!\'',
))
proxy::query returns true
proxy::query(array (
  0 => NULL,
  1 => 'SELECT \'Moin Johannes!\'',
))
proxy::query returns true

参见

mysqlnd_uh_set_statement_proxy

Installs a proxy for mysqlnd statements

说明

bool <span class="methodname">mysqlnd_uh_set_statement_proxy ( <span class="methodparam">MysqlndUhStatement &$statement_proxy )

Installs a proxy for mysqlnd statements. The proxy object will be used for all mysqlnd prepared statement objects, regardless which PHP MySQL extension (mysqli, mysql, PDO_MYSQL) has created them as long as the extension is compiled to use the mysqlnd library.

The function can be disabled with mysqlnd_uh.enable. If mysqlnd_uh.enable is set to false the function will not install the proxy and always return true. Additionally, an error of the type E_WARNING may be emitted. The error message may read like PHP Warning: mysqlnd_uh_set_statement_proxy(): (Mysqlnd User Handler) The plugin has been disabled by setting the configuration parameter mysqlnd_uh.enable = false. The proxy has not been installed [...].

参数

statement_proxy
The mysqlnd statement proxy object of type MysqlndUhStatement

返回值

Returns true on success. Otherwise, returns false

参见

目录

Change History

目录

The Change History lists major changes users need to be aware if upgrading from one version to another. It is a high level summary of selected changes that may impact applications or might even break backwards compatibility. See also the CHANGES file contained in the source for additional changelog information. The commit history is also available.

PECL/mysqlnd_uh 1.0 series

1.0.1-alpha

  • Release date: TBD
  • Motto/theme: bug fix release

Feature changes

  • Support of PHP 5.4.0 or later.
  • BC break: <span class="methodname">MysqlndUhConnection::changeUser requires additional passwd_len parameter.
  • BC break: MYSQLND_UH_VERSION_STR renamed to MYSQLND_UH_VERSION. MYSQLND_UH_VERSION renamed to MYSQLND_UH_VERSION_ID.
  • BC break: mysqlnd_uh.enabled configuration setting renamed to mysqlnd_uh.enable.

1.0.0-alpha

  • Release date: 08/2010
  • Motto/theme: Initial release

Mysqlnd connection multiplexing plugin

目录

The mysqlnd multiplexing plugin (mysqlnd_mux) multiplexes MySQL connections established by all PHP MySQL extensions that use the MySQL native driver (mysqlnd) for PHP.

The MySQL native driver for PHP features an internal C API for plugins, such as the connection multiplexing plugin, which can extend the functionality of mysqlnd. See the mysqlnd for additional details about its benefits over the MySQL Client Library libmysqlclient.

Mysqlnd plugins like mysqlnd_mux operate, for the most part, transparently from a user perspective. The connection multiplexing plugin supports all PHP applications, and all MySQL PHP extensions. It does not change existing APIs. Therefore, it can easily be used with existing PHP applications.

Note:

This is a proof-of-concept. All features are at an early stage. Not all kinds of queries are handled by the plugin yet. Thus, it cannot be used in a drop-in fashion at the moment.

Please, do not use this version in production environments.

Key Features

The key features of mysqlnd_mux are as follows:

  • Transparent and therefore easy to use:

    • Supports all of the PHP MySQL extensions.

    • Little to no application changes are required, dependent on the required usage scenario.

  • Reduces server load and connection establishment latency:

    • Opens less connections to the MySQL server.

    • Less connections to MySQL mean less work for the MySQL server. In a client-server environment scaling the server is often more difficult than scaling the client. Multiplexing helps with horizontal scale-out (scale-by-client).

    • Pooling saves connection time.

    • Multiplexed connection: multiple user handles share the same network connection. Once opened, a network connection is cached and shared among multiple user handles. There is a 1:n relationship between internal network connection and user connection handles.

    • Persistent connection: a network connection is kept open at the end of the web request, if the PHP deployment model allows. Thus, subsequently web requests can reuse a previously opened connection. Like other resources, network connections are bound to the scope of a process. Thus, they can be reused for all web requests served by a process.

Limitations

The proof-of-concept does not support unbuffered queries, prepared statements, and asynchronous queries.

The connection pool is using a combination of the transport method and hostname as keys. As a consequence, two connections to the same host using the same transport method (TCP/IP, Unix socket, Windows named pipe) will be linked to the same pooled connection even if username and password differ. Be aware of the possible security implications.

The proof-of-concept is transaction agnostic. It does not know about SQL transactions.

Note:

Applications must be aware of the consequences of connection sharing connections.

About the name mysqlnd_mux

The shortcut mysqlnd_mux stands for mysqlnd connection multiplexing plugin.

Concepts

目录

This explains the architecture and related concepts for this plugin. Reading and understanding these concepts is required to successfully use this plugin.

Architecture

The mysqlnd connection multiplexing plugin is implemented as a PHP extension. It is written in C and operates under the hood of PHP. During the startup of the PHP interpreter, in the module initialization phase of the PHP engine, it gets registered as a mysqlnd plugin to replace specific mysqlnd C methods.

The mysqlnd library uses PHP streams to communicate with the MySQL server. PHP streams are accessed by the mysqlnd library through its net module. The mysqlnd connection multiplexing plugin proxies methods of the mysqlnd library net module to control opening and closing of network streams.

Upon opening a user connection to MySQL using the appropriate connection functions of either mysqli, PDO_MYSQL or ext/mysql, the plugin will search its connection pool for an open network connection. If the pool contains a network connection to the host specified by the connect function using the transport method requested (TCP/IP, Unix domain socket, Windows named pipe), the pooled connection is linked to the user handle. Otherwise, a new network connection is opened, put into the poolm and associated with the user connection handle. This way, multiple user handles can be linked to the same network connection.

Connection pool

The plugins connection pool is created when PHP initializes its modules (MINIT) and free'd when PHP shuts down the modules (MSHUTDOWN). This is the same as for persistent MySQL connections.

Depending on the deployment model, the pool is used for the duration of one or multiple web requests. Network connections are bound to the lifespan of an operating system level process. If the PHP process serves multiple web requests as it is the case for Fast-CGI or threaded web server deployments, then the pooled connections can be reused over multiple connections. Because multiplexing means sharing connections, it can even happen with a threaded deployment that two threads or two distinct web requests are linked to one pooled network connections.

A pooled connection is explicitly closed once the last reference to it is released. An implicit close happens when PHP shuts down its modules.

Sharing connections

The PHP mysqlnd connection multiplexing plugin changes the relationship between a users connection handle and the underlying MySQL connection. Without the plugin, every MySQL connection belongs to exactly one user connection at a time. The multiplexing plugin changes. A MySQL connection is shared among multiple user handles. There no one-to-one relation if using the plugin.

Sharing pooled connections has an impact on the connection state. State changing operations from multiple user handles pointing to one MySQL connection are not isolated from each other. If, for example, a session variable is set through one user connection handle, the session variable becomes visible to all other user handles that reference the same underlying MySQL connection.

This is similar in concept to connection state related phenomens described for the PHP mysqlnd replication and load balancing plugin. Please, check the PECL/mysqlnd_ms documentation for more details on the state of a connection.

The proof-of-concept takes no measures to isolate multiplexed connections from each other.

安装/配置

目录

需求

PHP 5.5.0 or newer. Some advanced functionality requires PHP 5.5.0 or newer.

The mysqlnd_mux replication and load balancing plugin supports all PHP applications and all available PHP MySQL extensions (mysqli, mysql, PDO_MYSQL). The PHP MySQL extension must be configured to use mysqlnd in order to be able to use the mysqlnd_mux plugin for mysqlnd.

安装

安装此 PECL 扩展相关的信息可在手册中标题为 PECL 扩展的安装章节中找到。更多信息如新的发行版本、下载、源文件、 维护人员信息及变更日志等,都在此处: » https://pecl.php.net/package/mysqlnd_mux

运行时配置

这些函数的行为受 php.ini 中的设置影响。

名字 默认 可修改范围 更新日志
mysqlnd_mux.enable 0 PHP_INI_SYSTEM

这是配置指令的简短说明。

mysqlnd_mux.enable int
Enables or disables the plugin. If disabled, the extension will not plug into mysqlnd to proxy internal mysqlnd C API calls.

预定义常量

下列常量由此扩展定义,且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

Other

The plugins version number can be obtained using MYSQLND_MUX_VERSION or MYSQLND_MUX_VERSION_ID. MYSQLND_MUX_VERSION is the string representation of the numerical version number MYSQLND_MUX_VERSION_ID, which is an integer such as 10000. Developers can calculate the version number as follows.

Version (part) Example
Major*10000 1*10000 = 10000
Minor*100 0*100 = 0
Patch 0 = 0
MYSQLND_MUX_VERSION_ID 10000

MYSQLND_MUX_VERSION (string)
Plugin version string, for example, “1.0.0-prototype”.

MYSQLND_MUX_VERSION_ID (int)
Plugin version number, for example, 10000.

Change History

目录

This change history is a high level summary of selected changes that may impact applications and/or break backwards compatibility.

See also the CHANGES file in the source distribution for a complete list of changes.

PECL/mysqlnd_mux 1.0 series

1.0.0-pre-alpha

  • Release date: no package released, initial check-in 09/2012
  • Motto/theme: Proof of concept

Initial check-in. Essentially a demo of the mysqlnd plugin API.

Note:

This is the current development series. All features are at an early stage. Changes may happen at any time without prior notice. Please, do not use this version in production environments.

The documentation may not reflect all changes yet.

Mysqlnd Memcache plugin

目录

The mysqlnd memcache plugin (mysqlnd_memcache) is an PHP extension for transparently translating SQL into requests for the MySQL InnoDB Memcached Daemon Plugin (server plugin). It includes experimental support for the MySQL Cluster Memcached Daemon. The server plugin provides access to data stored inside MySQL InnoDB (respectively MySQL Cluster NDB) tables using the Memcache protocol. This PHP extension, which supports all PHP MySQL extensions that use mysqlnd, will identify tables exported in this way and will translate specific SELECT queries into Memcache requests.

mysqlnd_memcache data flow

Note:

This plugin depends on the MySQL InnoDB Memcached Daemon Plugin. It is not provided to be used with a stand-alone Memcached. For a generic query cache using Memcached look at the mysqlnd query cache plugin. For direct Memcache access look at the memcache and memcached extensions.

The MySQL native driver for PHP is a C library that ships together with PHP as of PHP 5.3.0. It serves as a drop-in replacement for the MySQL Client Library (libmysqlclient). Using mysqlnd has several advantages: no extra downloads are required because it's bundled with PHP, it's under the PHP license, there is lower memory consumption in certain cases, and it contains new functionality such as asynchronous queries.

The mysqlnd_mmemcache operates, for the most part, transparently from a user perspective. The mysqlnd memcache plugin supports all PHP applications, and all MySQL PHP extensions. It does not change existing APIs. Therefore, it can easily be used with existing PHP applications.

The MySQL Memcache plugins add key-value style access method for data stored in InnoDB resp. NDB (MySQL Cluster) SQL tables through the Memcache protocol. This type of key-value access if often faster than using SQL.

Key Features

The key features of PECL/mysqlnd_memcache are as follows.

  • Possible performance benefits

    • Client-side: light-weight protocol.

    • Server-side: no SQL parsing, direct access to the storage.

    • Please, run your own benchmarks! Actual performance results are highly dependent on setup and hardware used.

Limitations

The initial version is not binary safe. Due to the way the MySQL Memcache plugins works there are restrictions related to separators.

Prepared statements and asynchronous queries are not supported. Result set meta data support is limited.

The mapping information for tables accessible via Memcache is not cached in the plugin between requests but fetched from the MySQL server each time a MySQL connection is associated with a Memcache connection. See mysqlnd_memcache_set for details.

On the name

The shortcut mysqlnd_memcache stands for mysqlnd memcache plugin. Memcache refers to support of the MySQL Memcache plugins for InnoDB and NDB (MySQL Cluster). The plugin is not related to the Memcached cache server.

Quickstart and Examples

目录

The mysqlnd memcache plugin is easy to use. This quickstart will demo typical use-cases, and provide practical advice on getting started.

It is strongly recommended to read the reference sections in addition to the quickstart. The quickstart tries to avoid discussing theoretical concepts and limitations. Instead, it will link to the reference sections. It is safe to begin with the quickstart. However, before using the plugin in mission critical environments we urge you to read additionally the background information from the reference sections.

Setup

The plugin is implemented as a PHP extension. See also the installation instructions to install this extension.

Compile or configure the PHP MySQL extension (API) (mysqli, PDO_MYSQL, mysql). That extension must use the mysqlnd library as because mysqlnd_memcache is a plugin for the mysqlnd library. For additional information, refer to the mysqlnd_memcache installation instructions.

Then, load this extension into PHP and activate the plugin in the PHP configuration file using the PHP configuration directive named mysqlnd_memcache.enable.

示例 #1 Enabling the plugin (php.ini)

; On Windows the filename is php_mysqnd_memcache.dll
; Load the extension
extension=mysqlnd_memcache.so
; Enable it
mysqlnd_memcache.enable=1

Follow the instructions given in the » MySQL Reference Manual on installing the Memcache plugins for the MySQL server. Activate the plugins and configure Memcache access for SQL tables.

The examples in this quickguide assume that the following table exists, and that Memcache is configured with access to it.

示例 #2 SQL table used for the Quickstart

CREATE TABLE test(
  id CHAR(16),
  f1 VARCHAR(255),
  f2 VARCHAR(255),
  f3 VARCHAR(255),
  flags INT NOT NULL,
  cas_column INT,
  expire_time_column INT,
  PRIMARY KEY(id)
  ) ENGINE=InnoDB;

INSERT INTO test (id, f1, f2, f3) VALUES (1, 'Hello', 'World', '!');
INSERT INTO test (id, f1, f2, f3) VALUES (2, 'Lady', 'and', 'the tramp');

INSERT INTO innodb_memcache.containers(
  name, db_schema, db_table, key_columns, value_columns, 
  flags, cas_column, expire_time_column, unique_idx_name_on_key)
VALUES (
  'plugin_test', 'test', 'test', 'id', 'f1,f2,f3',
  'flags', 'cas_column', 'expire_time_column', 'PRIMARY KEY');

Usage

After associating a MySQL connection with a Memcache connection using mysqnd_memcache_set the plugin attempts to transparently replace SQL SELECT statements by a memcache access. For that purpose the plugin monitors all SQL statements executed and tries to match the statement string against MYSQLND_MEMCACHE_DEFAULT_REGEXP. In case of a match, the mysqlnd memcache plugin checks whether the SELECT is accessing only columns of a mapped table and the WHERE clause is limited to a single key lookup.

In case of the example SQL table, the plugin will use the Memcache interface of the MySQL server to fetch results for a SQL query like SELECT f1, f2, f3 WHERE id = n.

示例 #1 Basic example.

<?php
$mysqli = new mysqli("host", "user", "passwd", "database");
$memc = new Memcached();
$memc->addServer("host", 11211);
mysqlnd_memcache_set($mysqli, $memc);

/*
   This is a query which queries table test using id as key in the WHERE part
   and is accessing fields f1, f2 and f3. Therefore, mysqlnd_memcache
   will intercept it and route it via memcache.
*/
$result = $mysqli->query("SELECT f1, f2, f3 FROM test WHERE id = 1");
while ($row = $result->fetch_row()) {
    print_r($row);
}

/*
   This is a query which queries table test but using f1 in the WHERE clause.
   Therefore, mysqlnd_memcache can't intercept it. This will be executed
   using the MySQL protocol
*/
$mysqli->query("SELECT id FROM test WHERE f1 = 'Lady'");
while ($row = $result->fetch_row()) {
    print_r($row);
}
?>

以上例程会输出:

array(
    [f1] => Hello
    [f2] => World
    [f3] => !
)
array(
    [id] => 2
)

安装/配置

目录

需求

PHP: this extension requires PHP 5.4+, version PHP 5.4.4 or never. The required PHP extensions are PCRE (enabled by default), and the memcached extension version 2.0.x.

The mysqlnd_memcache Memcache plugin supports all PHP applications and all available PHP MySQL extensions (mysqli, mysql, PDO_MYSQL). The PHP MySQL extension must be configured with mysqlnd support.

For accessing InnoDB tables, this PHP extension requires MySQL Server 5.6.6 or newer with the InnoDB Memcache Daemon Plugin enabled.

For accessing MySQL Cluster NDB tables, this PHP extension requires MySQL Cluster 7.2 or newer with the NDB Memcache API nodes enabled.

安装

» PECL 扩展未与 PHP 捆绑。

安装此 PECL 扩展相关的信息可在手册中标题为 PECL 扩展的安装章节中找到。更多信息如新的发行版本、下载、源文件、 维护人员信息及变更日志等,都在此处: » https://pecl.php.net/package/mysqlnd_memcache

PECL 扩展的 DLL 当前不可用。参见 在 Windows 上构建章节。

运行时配置

这些函数的行为受 php.ini 中的设置影响。

名字 默认 可修改范围 更新日志
mysqlnd_memcache.enable 1 PHP_INI_SYSTEM Available since 1.0.0

这是配置指令的简短说明。

mysqlnd_memcache.enable int
Enables or disables the plugin. If disabled, the extension will not plug into mysqlnd to proxy internal mysqlnd C API calls.

Note:

This option is mainly used by developers to build this extension statically into PHP. General users are encouraged to build this extension as a shared object, and to unload it completely when it is not needed.

预定义常量

下列常量由此扩展定义,且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

MySQL Memcache Plugin related

MYSQLND_MEMCACHE_DEFAULT_REGEXP (string)
Default regular expression (PCRE style) used for matching SELECT statements that will be mapped into a MySQL Memcache Plugin access point, if possible. It is also possible to use <span class="function">mysqlnd_memcache_set, but the default approach is using this regular expression for pattern matching.

Assorted

The version number of this plugin can be obtained by using MYSQLND_MEMCACHE_VERSION or MYSQLND_MEMCACHE_VERSION_ID. MYSQLND_MEMCACHE_VERSION is the string representation of the numerical version number MYSQLND_MEMCACHE_VERSION_ID, which is an integer such as 10000. Developers can calculate the version number as follows.

Version (part) Example
Major*10000 1*10000 = 10000
Minor*100 0*100 = 0
Patch 0 = 0
MYSQLND_MEMCACHE_VERSION_ID 10000

MYSQLND_MEMCACHE_VERSION (string)
Plugin version string, for example, “1.0.0-alpha”.

MYSQLND_MEMCACHE_VERSION_ID (int)
Plugin version number, for example, 10000.

mysqlnd_memcache_get_config

Returns information about the plugin configuration

说明

array <span class="methodname">mysqlnd_memcache_get_config ( <span class="methodparam">mixed $connection )

This function returns an array of all mysqlnd_memcache related configuration information that is attached to the MySQL connection. This includes MySQL, the Memcache object provided via <span class="function">mysqlnd_memcache_set, and the table mapping configuration that was automatically collected from the MySQL Server.

参数

connection
A handle to a MySQL Server using one of the MySQL API extensions for PHP, which are PDO_MYSQL, mysqli or ext/mysql.

返回值

An array of mysqlnd_memcache configuration information on success, otherwise false.

The returned array has these elements:

Array Key Description
memcached Instance of Memcached associated to this MySQL connection by mysqlnd_memcache_set. You can use this to change settings of the memcache connection, or directly by querying the server on this connection.
pattern The PCRE regular expression used to match the SQL query sent to the server. Queries matching this pattern will be further analyzed to decide whether the query can be intercepted and sent via the memcache interface or whether the query is sent using the general MySQL protocol to the server. The pattern is either the default pattern (MYSQLND_MEMCACHE_DEFAULT_REGEXP) or it is set via mysqlnd_memcache_set.
mappings An associative array with a list of all configured containers as they were discovered by this plugin. The key for these elements is the name of the container in the MySQL configuration. The value is described below. The contents of this field is created by querying the MySQL Server during association to MySQL and a memcache connection using mysqlnd_memcache_set.
mapping_query An SQL query used during mysqlnd_memcache_set to identify the available containers and mappings. The result of that query is provided in the mappings element.
Mapping entry structure
Array Key Description
prefix A prefix used while accessing data via memcache. With the MySQL InnoDB Memcache Deamon plugin, this usually begins with @@ and ends with a configurable separator. This prefix is placed in front of the key value while using the memcache protocol.
schema_name Name of the schema (database) which contains the table being accessed.
table_name Name of the table which contains the data accessible via memcache protocol.
id_field_name Name of the database field (column) with the id used as key when accessing the table via memcache. Often this is the database field having a primary key.
separator The separator used to split the different field values. This is needed as memcache only provides access to a single value while MySQL can map multiple columns to this value.

Note:

The separator, which can be set in the MySQL Server configuration, should not be part of any value retrieved via memcache because proper mapping can't be guaranteed.

fields An array with the name of all fields available for this mapping.

范例

示例 #1 mysqlnd_memcache_get_config example

<?php
$mysqli = new mysqli("host", "user", "passwd", "database");
$memc = new Memcached();
$memc->addServer("host", 11211);
mysqlnd_memcache_set($mysqli, $memc);

var_dump(mysqlnd_memcache_get_config($mysqli));
?>

以上例程会输出:

array(4) {
  ["memcached"]=>
  object(Memcached)#2 (0) {
  }
  ["pattern"]=>
  string(125) "/^\s*SELECT\s*(.+?)\s*FROM\s*`?([a-z0-9_]+)`?\s*WHERE\s*`?([a-z0-9_]+)`?\s*=\s*(?(?=["'])["']([^"']*)["']|([0-9e\.]*))\s*$/is"
  ["mappings"]=>
  array(1) {
    ["mymem_test"]=>
    array(6) {
      ["prefix"]=>
      string(13) "@@mymem_test."
      ["schema_name"]=>
      string(4) "test"
      ["table_name"]=>
      string(10) "mymem_test"
      ["id_field_name"]=>
      string(2) "id"
      ["separator"]=>
      string(1) "|"
      ["fields"]=>
      array(3) {
        [0]=>
        string(2) "f1"
        [1]=>
        string(2) "f2"
        [2]=>
        string(2) "f3"
      }
    }
  }
  ["mapping_query"]=>
  string(209) "    SELECT c.name,
                          CONCAT('@@', c.name, (SELECT value FROM innodb_memcache.config_options WHERE name = 'table_map_delimiter')) AS key_prefix, 
                          c.db_schema, 
                          c.db_table, 
                          c.key_columns, 
                          c.value_columns, 
                          (SELECT value FROM innodb_memcache.config_options WHERE name = 'separator') AS sep 
                     FROM innodb_memcache.containers c"
}

参见

  • mysqlnd_memcache_set

mysqlnd_memcache_set

Associate a MySQL connection with a Memcache connection

说明

bool <span class="methodname">mysqlnd_memcache_set ( <span class="methodparam">mixed $mysql_connection [, <span class="type">Memcached $memcache_connection [, <span class="methodparam">string $pattern [, callable $callback ]]] )

Associate mysql_connection with memcache_connection using pattern as a PCRE regular expression, and callback as a notification callback or to unset the association of mysql_connection.

While associating a MySQL connection with a Memcache connection, this function will query the MySQL Server for its configuration. It will automatically detect whether the server is configured to use the InnoDB Memcache Daemon Plugin or MySQL Cluster NDB Memcache support. It will also query the server to automatically identify exported tables and other configuration options. The results of this automatic configuration can be retrieved using <span class="function">mysqlnd_memcache_get_config.

参数

mysql_connection
A handle to a MySQL Server using one of the MySQL API extensions for PHP, which are PDO_MYSQL, mysqli or ext/mysql.

memcache_connection
A Memcached instance with a connection to the MySQL Memcache Daemon plugin. If this parameter is omitted, then mysql_connection will be unassociated from any memcache connection. And if a previous association exists, then it will be replaced.

pattern
A regular expression in Perl Compatible Regular Expression syntax used to identify potential Memcache-queries. The query should have three sub patterns. The first subpattern contains the requested field list, the second the name of the ID column from the query and the third the requested value. If this parameter is omitted or os set to null, then a default pattern will be used.

callback
A callback which will be used whenever a query is being sent to MySQL. The callback will receive a single bool parameter telling if a query was sent via Memcache.

返回值

true if the association or disassociation is successful, otherwise false if there is an error.

范例

示例 #1 mysqlnd_memcache_set example with var_dump as a simple debugging callback.

<?php
$mysqli = new mysqli("host", "user", "passwd", "database");
$memc = new Memcached();
$memc->addServer("host", 11211);
mysqlnd_memcache_set($mysqli, $memc, NULL, 'var_dump');

/* This query will be intercepted and executed via Memcache protocol */
echo "Sending query for id via Memcache: ";
$mysqli->query("SELECT f1, f2, f3 FROM test WHERE id = 1");

/* f1 is not configured as valid key field, this won't be sent via Memcache */
echo "Sending query for f1 via Memcache: ";
$mysqli->query("SELECT id FROM test WHERE f1 = 1");

mysqlnd_memcache_set($mysqli);

/* Now the regular MySQL protocol will be used */
echo "var_dump won't be invoked: ";
$mysqli->query("SELECT f1, f2, f3 WHERE id = 1");

?>

以上例程会输出:

Sending query for id via Memcache: bool(true)
Sending query for f1 via Memcache: bool(false)
var_dump won't be invoked: 

参见

  • mysqlnd_memcache_get_config

目录

Change History

目录

This change history is a high level summary of selected changes that may impact applications and/or break backwards compatibility.

See also the CHANGES file in the source distribution for a complete list of changes.

PECL/mysqlnd_memcache 1.0 series

1.0.0-alpha

  • Release date: TBD
  • Motto/theme: Basic mapping of SQL SELECT to a MySQL Memcache plugin access.

The initial release does map basic SQL SELECT statements to a MySQL Memcache plugin access. This bares potential performance benefits as the direct key-value access to MySQL storage using the Memcache protocol is usually faster than using SQL access.


本站为非盈利网站,作品由网友提供上传,如无意中有侵犯您的版权,请联系删除