使用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);
  }

请参考上述代码,在连接数据库时引用了数据库的信息。请查看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);

首先关于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();

此外,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操作(创建、读取、更新、删除)有了一些初步的理解。

bannerAds