感觉比直接弄SQL语句高级,但还不到ORM的封装。

一步一步进化。

app.json

{
    "db": {
        "user": "root",
        "password": "xxxx",
        "host": "10.2.3.4",
        "port": "3306",
        "dbname": "bookstore"
    }
}

config.php

<?php

namespace Bookstore\Utils;

use Bookstore\Exceptions\NotFoundException;

require_once __DIR__ . '/NotFoundException.php';

class Config {
    private $data;
    //类静态变量,保证变量唯一性
    private static $instance;

    //构造函数私有化,类外部不可以调用.
    private function __construct() {
        $json = file_get_contents(__DIR__ . '/app.json');
        $this->data = json_decode($json, true);
    }

    //单例模式,保证只实例化一个类.
    public static function getInstance() {
        if (self::$instance == null) {
            //是可以自己实例化自己的.
            self::$instance = new Config();
        }
        return self::$instance;
    }

    public function get($key) {
        if (!isset($this->data[$key])) {
            throw new NotFoundException("Key $key not in config.");
        }
        return $this->data[$key];
    }
}
?>

test.php

<?php
//使用命名空间,易于在大型应用中管理和组织php类.

use Bookstore\Utils\Config;

//命名空间可以直接use,但如果这个命名空间没有在标准约定位置,且没有自动载入的话,需要使用require来手工定位一下.
require_once __DIR__ . '\Config.php';

header("content-type:text/html;charset=utf-8");
$dbConfig = Config::getInstance()->get("db");

$connStr = "mysql:host={$dbConfig['host']};port={$dbConfig['port']};dbname={$dbConfig['dbname']};charset=utf8";

$db = new \PDO($connStr,    $dbConfig['user'], $dbConfig['password']);
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

$query = 'SELECT * FROM book WHERE author = :author';
$statement = $db->prepare($query);
$statement->bindValue('author', 'George Orwell');
$statement->execute();
$rows = $statement->fetchAll();
foreach ($rows as $row) {
    var_dump($row);
}
echo "<br/>";
$query = <<<SQL
INSERT INTO book(isbn, title, author, price)
VALUES(:isbn, :title, :author, :price)
SQL;
$statement = $db->prepare($query);
$params = [
    'isbn' => '9781413108614',
    'title' => 'Iliad',
    'author' => 'Homer',
    'price' => 9.25
];
$statement->execute($params);
$result = $db->exec($query);
echo $db->lastInsertId();
echo "<br/>";

function addBook(int $id, int $amount=1):void {
    $query = 'UPDATE book SET stock = stock + :n WHERE id = :id';
    $statement = $db->prepare($query);
    $statement->bindValue('id', $id);
    $statement->bindValue('n', $amount);

    if (!$statement->execute()) {
        throw new Exception($statement->errorInfo()[2]);
    }
}

function addSale($db, int $userId, array $bookIds):void {
    $db->beginTransaction();
    try {
        $query = 'INSERT INTO sale(customer_id, date)'
            . 'VALUES(:id, NOW())';
        $statement = $db->prepare($query);
        if (!$statement->execute(['id'=> $userId])) {
            throw new Exception($statement->errorInfo()[2]);
        }
        $saleId = $db->lastInsertId();

        $query = 'INSERT INTO sale_book(book_id, sale_id)'
            . 'VALUES(:book, :sale)';
        $statement = $db->prepare($query);
        $statement->bindValue('sale', $saleId);
        foreach ($bookIds as $bookId) {
            $statement->bindValue('book', $bookId);
            if (!$statement->execute()) {
                throw new Exception($statement->errorInfo()[2]);
            }
        }
        $db->commit();
    } catch (Exception $e) {
        $db->rollback();
        throw $e;
    }
}

try {
    addSale($db, 1, [1, 2, 300]);
} catch (Exception $e) {
    echo 'Error adding sale: ' . $e->getMessage();
}

try {
    addSale($db, 1, [1, 2, 3]);
} catch (Exception $e) {
    echo 'Error adding sale: ' . $e->getMessage();
}

?>

输出

array(6) { ["id"]=> string(1) "1" ["isbn"]=> string(13) "9780882339726" ["title"]=> string(4) "1984" ["author"]=> string(13) "George Orwell" ["stock"]=> string(2) "12" ["price"]=> string(3) "8.7" } array(6) { ["id"]=> string(1) "3" ["isbn"]=> string(13) "9780736692427" ["title"]=> string(11) "Animal Farm" ["author"]=> string(13) "George Orwell" ["stock"]=> string(1) "8" ["price"]=> string(4) "4.06" }
0
Error adding sale: Cannot add or update a child row: a foreign key constraint fails (`bookstore`.`sale_book`, CONSTRAINT `sale_book_ibfk_2` FOREIGN KEY (`book_id`) REFERENCES `book` (`id`))

PHP操作MYSQL--PDO的更多相关文章

  1. MySQL原生API、MySQLi面向过程、MySQLi面向对象、PDO操作MySQL

    [转载]http://www.cnblogs.com/52fhy/p/5352304.html 本文将举详细例子向大家展示PHP是如何使用MySQL原生API.MySQLi面向过程.MySQLi面向对 ...

  2. php笔记08:数据库编程---使用php的MySQL扩展库操作MySQL数据库

    1.使用php的MySQL扩展库操作MySQL数据库: php有3种方式操作MySQL数据库 (1)mysql扩展库 (2)mysqli扩展库 (3)pdo     mysql扩展库与mysql数据库 ...

  3. php mysql PDO使用

    <?php $dbh = new PDO('mysql:host=localhost;dbname=access_control', 'root', ''); $dbh->setAttri ...

  4. ASP.NET Core 1.0 使用 Dapper 操作 MySql(包含事务)

    操作 MySql 数据库使用MySql.Data程序包(MySql 开发,其他第三方可能会有些问题). project.json 代码: { "version": "1. ...

  5. Python(九) Python 操作 MySQL 之 pysql 与 SQLAchemy

    本文针对 Python 操作 MySQL 主要使用的两种方式讲解: 原生模块 pymsql ORM框架 SQLAchemy 本章内容: pymsql 执行 sql 增\删\改\查 语句 pymsql ...

  6. EF操作MySql

    EF的CodeFrist操作MySql的提前准备: 1.安装两个包:MySql.Data和MySql.Data.Entity,在VS中程序包管理器中添加2个包.(备注需要的VS2015,并且EF6支持 ...

  7. .NET Core 使用Dapper 操作MySQL

    MySQL官方驱动:http://www.cnblogs.com/linezero/p/5806814.html .NET Core 使用Dapper 操作MySQL 数据库, .NET Core 使 ...

  8. asp.net core 1.1 升级后,操作mysql出错的解决办法。

    遇到问题 core的版本从1.0升级到1.1,操作mysql数据库,查询数据时遇到MissingMethodException问题,更新.插入操作没有问题. 如果你也遇到这个问题,请参照以下步骤进行升 ...

  9. 练习:python 操作Mysql 实现登录验证 用户权限管理

    python 操作Mysql 实现登录验证 用户权限管理

  10. Python操作MySQL

    本篇对于Python操作MySQL主要使用两种方式: 原生模块 pymsql ORM框架 SQLAchemy pymsql pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb ...

随机推荐

  1. 微信第三方平台代公众号发起网页授权 48001 api unauthorized 问题

    https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&gr ...

  2. 依赖注入之unity(winform方式)

    依赖注入之unity(winform方式) 要讲unity就必须先了解DI和IOC及DIP,如下链接提供DI和IOC的基础:https://www.cnblogs.com/zlp520/p/12015 ...

  3. kali 命令

    1.添加用户 如下命令是用root执行的 adduser dong 会直接在/home 目录创建 dong 目录 2.将用户划分到某个组 gpasswd -a user group 3.ifconfi ...

  4. SWIG 3 中文手册——2. 引言

    目录 2 引言 2.1 SWIG 是什么? 2.2 为什么使用 SWIG? 2.3 一个 SWIG 示例 2.3.1 SWIG 接口文件 2.3.2 swig 命令 2.3.3 构建 Perl5 模块 ...

  5. 不能随便用get和set

    有些对象呢,保存一半.如果你只提供get和set,那么备份不了数据. previousState的get和set还是最新的 wtforms InputRequired: DataRequired: i ...

  6. Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call错误

    我这边新增的接口之后编译,启动debug后提示这个问题, 在网上找了一段时间,感觉各大神说的都好有道理,但是没有作用 so,尝试对整个工程重新编译(理论上只要重新编译修改的文件影响到的地方)

  7. Android -- SEGV_MAPERR,SEGV_ACCERR

    Per siginfo.h: SEGV_MAPERR means you tried to access an address that doesn’t map to anything. SEGV_A ...

  8. Python协程介绍(转)

    原文:https://www.liaoxuefeng.com/wiki/897692888725344/923057403198272 协程,又称微线程,纤程.英文名Coroutine. 协程的概念很 ...

  9. MyBatis系列(二) MyBatis接口绑定与多参数传递

    前言 通过上一篇博文的,已经可以做到通过MyBatis连接数据库,现在再来介绍一种方法通过接口绑定SQL语句. 不使用接口绑定的方式 不使用接口绑定的方式,是通过调用SqlSession中的selec ...

  10. Mybatis+MySql 一个标签中执行多条sql语句

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/cxfly957/article/details/77896590 MySql默认是不支持这种骚操作的 ...