使用PHP创建博客
首先。
为了学习PHP,我这次尝试创建了一个博客。由于我只专注于让应用程序运行起来,所以这次仅进行了最基本的实现,没有涉及以下内容的实现。
-
CSRF対策
例外処理
這篇文章旨在回顧和記錄我在使用php實現時的經驗和日常備忘錄。如果有任何不正確之處,請友好地指正並教導我。
与CRUD处理相关的每个方法
<?php
namespace Myapp;
class Blog {
private $_db;
public function __construct() {
$this->_db = new \PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
}
//全件取得。
public function getAll(){
$stmt = $this->_db->query("select * from blogs order by id desc");
return $stmt->fetchAll(\PDO::FETCH_OBJ);
}
//URLからIDを取得しPDOオブジェクトで抽出。
public function show(){
$url = $_SERVER["REQUEST_URI"];
$id = substr($url, -2);
$sql = sprintf("select * from blogs where id = %s", $id );
$stmt = $this->_db->query($sql);
return $stmt->fetch(\PDO::FETCH_OBJ);
}
//挿入
public function create() {
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$title = $_POST["title"];
$content = $_POST["content"];
$sql = "insert into blogs (title, content) values (:title, :content)";
$stmt = $this->_db->prepare($sql);
$stmt->execute([':title' => $title, ':content' => $content]);
header('Location:http://' . SITE_URL);
}
}
//削除
public function delete(){
$url = $_SERVER["REQUEST_URI"];
$id = substr($url, -2);
$sql = sprintf("delete from blogs where id = %d", $id );
$stmt = $this->_db->query($sql);
}
//更新
public function update() {
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$url = $_SERVER["REQUEST_URI"];
$id = substr($url, -2);
$title = $_POST["title"];
$content = $_POST["content"];
$sql = "update blogs set title = ?, content = ? where id = ?";
$stmt = $this->_db->prepare($sql);
$stmt->bindValue(1, $title);
$stmt->bindValue(2, $content);
$stmt->bindValue(3, $id);
$stmt->execute();
}
}
}
?>
关于构建
public function __construct() {
$this->_db = new \PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
}
<?php
namespace Myapp;
class Blog {
private $_db;
public function __construct() {
$this->_db = new \PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
}
//全件取得。
public function getAll(){
$stmt = $this->_db->query("select * from blogs order by id desc");
return $stmt->fetchAll(\PDO::FETCH_OBJ);
}
//URLからIDを取得しPDOオブジェクトで抽出。
public function show(){
$url = $_SERVER["REQUEST_URI"];
$id = substr($url, -2);
$sql = sprintf("select * from blogs where id = %s", $id );
$stmt = $this->_db->query($sql);
return $stmt->fetch(\PDO::FETCH_OBJ);
}
//挿入
public function create() {
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$title = $_POST["title"];
$content = $_POST["content"];
$sql = "insert into blogs (title, content) values (:title, :content)";
$stmt = $this->_db->prepare($sql);
$stmt->execute([':title' => $title, ':content' => $content]);
header('Location:http://' . SITE_URL);
}
}
//削除
public function delete(){
$url = $_SERVER["REQUEST_URI"];
$id = substr($url, -2);
$sql = sprintf("delete from blogs where id = %d", $id );
$stmt = $this->_db->query($sql);
}
//更新
public function update() {
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$url = $_SERVER["REQUEST_URI"];
$id = substr($url, -2);
$title = $_POST["title"];
$content = $_POST["content"];
$sql = "update blogs set title = ?, content = ? where id = ?";
$stmt = $this->_db->prepare($sql);
$stmt->bindValue(1, $title);
$stmt->bindValue(2, $content);
$stmt->bindValue(3, $id);
$stmt->execute();
}
}
}
?>
public function __construct() {
$this->_db = new \PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
}
请参考上述代码,在连接数据库时引用了数据库的信息。请查看config.php文件以了解详细的代码内容。
ini_set("display_errors", 1);
define('PDO_DSN', 'mysql:dbname=blog_app;host=localhost;charset=utf8;unix_socket=/tmp/mysql.sock');
define("SITE_URL", $_SERVER["HTTP_HOST"]);
define('DB_USERNAME', 'admin');
define('DB_PASSWORD', 'admin1234');
这里的PDO类中对于MySQL数据库的访问出现了问题,显示了SQLSTATE[HY000] [2002] No such file or directory的错误。意思是目录不存在。经过调查,可能是由于MySQL指定的目录路径不正确等原因。因此,直接通过添加unix_socket=/tmp/mysql.sock’并指定路径来解决了这个错误。另外,通过将host:localhost修改为host:127.0.0.1并指定IP地址也解决了错误,但是不清楚解决的原因,请有知识的人提供解释。
关于查询事项
public function getAll() {
$stmt = $this->_db->query("select * from todos order by id desc");
//結果をオブジェクト形式で返す
return $stmt->fetchAll(\PDO::FETCH_OBJ);
public function getAll() {
$stmt = $this->_db->query("select * from todos order by id desc");
//結果をオブジェクト形式で返す
return $stmt->fetchAll(\PDO::FETCH_OBJ);
首先关于query的问题,getAll方法中的SQL语句仅执行query操作。似乎可以理解为若要执行固定的SQL语句,则使用query。因此,当使用不需要分配变量的简单的SQL语句时,query是一个不错的选择。
关于”准备”和”执行”
//create処理での変数の扱い
$sql = "insert into blogs (title, content) values (:title, :content)";
$stmt = $this->_db->prepare($sql);
$stmt->execute([':title' => $title, ':content' => $content]);
header('Location:http://' . SITE_URL);
//update処理での変数の扱い
$sql = "update blogs set title = ?, content = ? where id = ?";
$stmt = $this->_db->prepare($sql);
$stmt->bindValue(1, $title);
$stmt->bindValue(2, $content);
$stmt->bindValue(3, $id);
$stmt->execute();
//create処理での変数の扱い
$sql = "insert into blogs (title, content) values (:title, :content)";
$stmt = $this->_db->prepare($sql);
$stmt->execute([':title' => $title, ':content' => $content]);
header('Location:http://' . SITE_URL);
//update処理での変数の扱い
$sql = "update blogs set title = ?, content = ? where id = ?";
$stmt = $this->_db->prepare($sql);
$stmt->bindValue(1, $title);
$stmt->bindValue(2, $content);
$stmt->bindValue(3, $id);
$stmt->execute();
此外,prepare和execute在使用上通常是作为一组使用的。通过以这种方式处理,可以在SQL查询中的参数指定部分写入“:名称”或问号“?”的参数标记来处理。
举个例子,当通过create方法处理时,会将变量如“:名称”一样的变量分配给SQL语句。
在prepare方法中设置SQL并在执行时通过数组传递值。
再看一下更新处理,这里使用了问号”?”作为占位符。
类似地,在准备阶段设置了SQL语句后,再通过绑定来传递值。
bindValue函数的参数是(从左到右的顺序,要设置的值)。
然后通过execute来执行。
此外,通过进一步的调查还发现它也可以作为SQL注入的防护措施,但这里不详细讨论。
从URL中获取ID
在这次实施中的关键是在相应的文章详细页面上显示,关键是如何获取并移动到该文章的id。我想到了在Rails中,参数params会自动将id传递到URL中,所以我考虑从URL中获取id。
首先,我尝试在列表页面的详细按钮中嵌入了id。
<li class="show"><a href="/show.php?id=<?php echo h($blog->id)?>">詳細</a></li>
从那里提取URL中的ID。
$url = $_SERVER["REQUEST_URI"];
$id = substr($url, -2);
//urlの中身はこれです。
//http://localhost:8888/show.php?id=88
//substrで後ろから2番目以降の文字である88を取得しています。
如果能做到这一点,那后面只需要使用该ID来处理SQL即可。
而且我不太清楚这种实现方式是否好,如果有其他实现方法,请告诉我。
最后
这次学习PHP让我受益匪浅的是学会操作SQL和处理数据库。虽说晚了些,但据说SQL的处理方式会影响性能,所以我打算继续学习SQL。我自己以前在使用Rails实现服务器端时完全依赖ActiveRecord,对于SQL的理解非常有限,重新认识到了这一点。
通过这次学习,我认为我对于php中的CRUD操作(创建、读取、更新、删除)有了一些初步的理解。