Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHP最佳实践之数据库 #7

Open
xx19941215 opened this issue Jul 20, 2017 · 0 comments
Open

PHP最佳实践之数据库 #7

xx19941215 opened this issue Jul 20, 2017 · 0 comments

Comments

@xx19941215
Copy link
Owner

PDO扩展

PHP原生提供了PDO扩展,意思是PHP数据对象。

数据库链接和DSN

DSN是指数据源名称,提供数据库链接的详细信息。一般包含以下信息:

  • 主机名或者IP地址
  • 端口号
  • 数据库名
  • 字符集

以上信息构成的DSN可以用于PDO类构造函数的第一个参数,第二个和第三个参数分别是数据库的用户名和密码。如果数据库需要认证,则需要提供这两个 参数。

<?php
try {
    $pdo = new PDO(
        'mysql:host = 127.0.0.1;dbname=books;port=3306;charset=utf8',
        'USERNAME',
        'PASSWORD'
    );
} catch(PDOException $e) {
    echo "Database connection failed";
    exit;
}
保证密码凭证的安全

把数据库凭证保存在一个位于文档根目录之外的配置文件中,然后在需要的文件中导入这个文件。

预处理语句

在SQL中使用用户的输入时,一定要过滤。因此需要使用PDO扩展的预处理语句和参数绑定,这项操作非常简单。预处理语句是PDO对象的实例,不过我们很少直接去实例化这个类,而是通过PDO实例的prepare方法获得预处理语句的对象。这个方法得第一个参数是一个sql语句字符串,返回值是一个PDOStatement实例:

<?php
$sql = 'SELECT id FROM users WHERE email = :email';
$statement = $pdo->prepare($sql);

在这个SQL语句中,email这个值可以安全的绑定任何值。

<?php
$sql = 'SELECT id FROM users WHERE email = :email';
$statement = $pdo->prepare($sql);
$email =  filter_input(INPUT_GET, 'email');
$statement->bindValue(':email', $email);

预处理语句会自动过滤$email的值。PDOStatement的第三个参数可以制定绑定值的类型,不填的话默认就是字符串类型。可选的常量类型如下

  • PDO::PARAM_BOOL
  • PDO::PARAM_NULL
  • PDO::PARAM_INT
  • PDO::PARAM_STR(默认值)
查询结果

如果执行的是select方法,返回的数据我们需要使用fetch()、fetchAll()、fetchColumn()和fetchObject()方法获取查询结果。

//把预处理语句获得的结果当成关联数组处理
$sql = 'SELECT id, email FROM users WHERE email = :email';
$statement = $pdo->prepare($sql);
$email = filter_input(INPUT_GET, 'email');
$statement->bindValue(':email', $email);
$stament->execute();
//迭代结果
while(($result = $statement->fetch(PDO::FETCH_ASSOC)) !== false) {
    echo $result['email'];
}

fetch、fetchAll方法的参数可选

  • PDO::FETCH_ASSOC:返回一个关联数组
  • PDO::FETCH_NUM:返回一个键为数字的数组,数组的键是数据库列在查询结果中的索引
  • PDO::FETCH_BOTH:返回一个既有键为列名又有键为数字的数组。
  • PDO::FETCH_OBJ:让fetch()和fetchAll()返回一个对象,对象的属性是数据库的列名。
    不推荐使用fetchAll(),除非你可以十分确定可用内存放得下整个查询结果。如果只关心查询结果中的一列,可以使用fetchColumn()方法,这个方法的作用和fetch()方法类似,返回查询结果中下一行的某一列,该方法只有一个参数用于制定所需要的索引。
// 构建并执行SQL查询
$sql = 'SELECT id, name FROM users WHERE email = :email';
$statement = $pdo->prepare($sql);
$email = filter_input(INPUT_GET, 'email');
$statement->bindValue(':email',  $email);
$statement->execute();

while(($emal = $statament->fetchCoulmn(1)) !== false) {
    echo $email;
}

因为在SQL语句中,email出现在了第二个字段的位置,所以这里使用索引1取出来。我们还可以使用fetchObj()方法来获取查询结果中的行,这个方法把行行当成对象,对象的属性是查询结果中的列。

// 构建并执行SQL查询
$sql = 'SELECT id, name FROM users WHERE email = :email';
$statement = $pdo->prepare($sql);
$email = filter_input(INPUT_GET, 'email');
$statement->bindValue(':email',  $email);
$statement->execute();

while(($result = $statament->fetchObj()) !== false) {
    echo $result->email;
}
事务

事务是指把一系列数据库语句当成单个的逻辑执行单元执行,也就是说事务中的一系列SQL查询要么都成功,要么不执行。事务的原子性能保证数据的一致性、安全性和持久性。事务还有一个很好的副作用就是提升性能,因为事务是把多个查询排成队列,一次性全部执行。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant