这一章主要讲解PHP操做数据库的应用。须要具有一些数据库前置知识,至少掌握mysql和redis的crud操做。就算不懂数据库的知识也无所谓,数据库语言都很是简单,从字面意义就能明白是在作什么。php
PHP链接数据库的方式有2种:mysql
MySQLi extension ("i" 意为 improved)laravel
PDO (PHP Data Objects)redis
二者的区别在于MySQLi只支持mysql,而PDO支持12种数据库。sql
为了方便,咱们只学习PDO的使用便可。由于咱们不能只会链接MySQL。这样会让咱们投入的时间性价比更高。数据库
PDO和go的go-sql-driver,Java的JDBC做用是同样的,连使用方法几乎都很是一致。作法都是建立一个链接实例,经过链接实例执行sql。api
PHP7以后,php自动具有了PDO,可使用phpinfo函数查看是否开启了PDO。数组
利用上一章学习到的路由和控制器知识,写一个RESTfulAPI来查看php环境。浏览器
建立路由composer
Route::get('phpinfo', 'EnvironmentController');
建立控制器
class EnvironmentController extends Controller { public function __invoke() { // 注意须要链接一个空字符串,由于phpinfo没有toString return phpinfo() . ''; } }
而后在浏览器访问http://homestead.test/api/v1/phpinfo
。你应该会看到很是多的数据,能够直接搜索PDO关键字,看到以下内容就表示当前运行环境的PDO是支持的。
建立一个PDO实例,传入3个构造参数。第1个是数据库链接,第2个是用户名,第3个是用户密码。
function connDB($dbname = 'test') { $servername = "localhost"; $username = "homestead"; $password = "secret"; try { $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); } catch (PDOException $e) { return $e->getMessage(); } }
使用建立出来的PDO实例conn来调用query方法,传入要执行的sql做为参数。
query方法返回bool值,成功为true,失败为false。
失败时还能够经过conn访问errorCode和errorInfo来获取错误信息。
$sql = "CREATE DATABASE test"; if ($conn->query($sql) == true) { return "数据库建立成功"; } else { return [ 'errorCode' => $conn->errorCode(), 'errorInfo:' => $conn->errorInfo() ]; }
建立表和建立数据库的操做同样,只是执行的sql不一样。
插入insert、查询select、修改update、删除delete四种操做均可以使用exec
方法来执行,可是这个方法不返回任何值。只能经过try/catch
来捕获异常来验证是否成功。
$conn->exec($sql);
设置错误模式,用于抛出异常。若是不设置,sql执行失败也不会抛出异常。
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
开启事务$conn->beginTransaction();
提交事务$conn->commit();
回滚事务$conn->rollback();
开启事务后开始执行sql语句,执行完毕提交事务。开启异常捕获,若是出现异常,执行回滚操做。
预处理语句就是定义模板,预留?
标记。例如:
insert into user (name, age, email) VALUES(?, ?, ?)
使用方法:
1.使用conn的prepare方法建立模板并返回一个对象stmt。其中字符串模板的填充字段用:前缀来修饰。
2.调用stmt的bindParam方法来绑定字段和值。接受2个参数,第1个参数是字段,第2个参数是值的变量名。
3.绑定后,执行stmt的方法execute来执行模板sql。
4.以后再次修改值时,直接修改变量的值,再次执行stmt的方法execute便可。
try { $stmt = $conn->prepare("insert into user (name, age, email, gender) VALUES(:name, :age, :email, :gender)"); $name = "张三"; $age = 134; $email = "@@@.@"; $gender = "男"; $stmt->bindParam(':name', $name); $stmt->bindParam(':age', $age); $stmt->bindParam(':email', $email); $stmt->bindParam(':gender', $gender); $stmt->execute(); // 再次插入行 $name = "李四"; $age = 22; $email = "lisi@gmail.com"; $stmt->execute(); return "插入成功"; } catch (PDOException $e) { return $e->getMessage(); }
这部分其实没什么可讲的东西,框架作的事,无非就是在PDO或mysqli基础上进行封装,简化咱们的操做而已。若是你是一直读过来的同窗,应该发现了一个问题。从学框架应用开始,讲的内容愈来愈含糊了。其实,这些框架的API我并非死记硬背的。大多数状况下,我都是先读一遍官方文档,而后针对经常使用的API写一些Demo测试。以后就是实战了。在实战中,若是发现有些需求处理的不够优雅,就会在去官方文档和社区寻找对应的更优解决方案。对我来说,学习框架的各类API是一件吃力不讨好的事。
Laravel 能使用原生 SQL、流畅的查询构造器 和 Eloquent ORM 在各类数据库后台与数据库进行很是简单的交互。
使用DBuse Illuminate\Support\Facades\DB;
.
执行查询DB::select('select * from users where active = ?', [1]);
,返回值始终是数组。
执行插入DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']);
执行更新$affected = DB::update('update users set votes = 100 where name = ?', ['John']);
,返回更新的行数。
执行删除$deleted = DB::delete('delete from users');
,返回删除的行数。
运行普通语句DB::statement('drop table users');
无返回值。
使用db的transaction方法,参数是个函数,在里面执行sql。
DB::transaction(function () { DB::table('users')->update(['votes' => 1]); // 这里写sql DB::table('posts')->delete(); });
看到这里,你应该发现,咱们用框架作的事,和前面学的PDO作的事基本上是同样的,区别只是写法不一样。
那为何还要再学一遍呢?由于咱们要使用框架,框架帮助咱们处理了不少异常问题和边界问题,简化咱们的操做。
这里我不想再讲下去了,由于我不必把官方文档的API挨个演示一遍。至于更高级的操做,如构造器和eloquent ORM,若是感兴趣,建议你去中文社区进行学习这一部分的内容。https://learnku.com/docs/laravel/5.8/database/3925
其实在咱们目前的项目中,关于redis的使用颇有限。这里不说redis集群的使用方式,只说下redis的单机应用。
这里假设你已经在本机安装好redis。
关于redis的可视化管理工具,推荐 Redis Desktop Manager。
首先在项目中安装predis包
composer require predis/predis
安装predis的过程当中可能会遇到一个异常信息:
the requested PHP extension fileinfo is missing from your system
意思是没有开启fileinfo扩展,须要在你PHP环境的php.ini文件中修改一行配置,若是没有这行配置那么就添加上。
extension=php_fileinfo.dll
若是你的redis默认配置没有修改,那么项目中的配置也都不须要修改。
若是你的redis不是本机的,或者修改了端口等,须要在项目中的config/database.php和.env文件中分别修改配置。
database.php相关配置
'redis' => [
'client' => env('REDIS_CLIENT', 'predis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'predis'),
'prefix' => Str::slug(env('APP_NAME', 'laravel'), '_').'_database_',
],
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
'cache' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
],
.evn相关配置。
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
predis的相关操做仍是很是简单的,基本上都和redis的原生操做一致。
存值Redis::set('key', 'value');
取值Redis::get('key');
检测某值是否存在Redis::exists('user_key')
设置过时时间Redis::setex('str', 10, 'bar');
删除Redis::del('key');
redis的操做多达十几种,这里就再也不继续罗列,更多操做可查阅:https://packagist.org/packages/predis/predis
这一章学习了在原生PHP和框架中操做mysql和redis的方式