前提
ローカル環境(xampp)で開発していたphpアプリをHerokuにデプロイしようとしたところ、エラーが起きてしまいました。エラーの内容は「クラスが読み込めません」なのですが、解決方法が分かりません。
実現したいこと
- 現在発生しているエラーを解決したい
発生している問題・エラーメッセージ
2022-06-30T04:30:54.670095+00:00 heroku[router]: at=info method=GET path="/public/signin.php" host=evenosche.herokuapp.com request_id=d1fe0fba-94d3-46f3-9af0-06e89af59118 fwd="49.104.12.79" dyno=web.1 connect=0ms service=22ms status=500 bytes=279 protocol=https 2022-06-30T04:30:54.671371+00:00 app[web.1]: [30-Jun-2022 04:30:54 UTC] PHP Fatal error: Uncaught Error: Class "LocalMyStudy\Evenosche\Classes\Dao\UserDAO" not found in /app/public/signin.php:29 2022-06-30T04:30:54.671386+00:00 app[web.1]: Stack trace: 2022-06-30T04:30:54.671400+00:00 app[web.1]: #0 {main} 2022-06-30T04:30:54.671551+00:00 app[web.1]: thrown in /app/public/signin.php on line 29 2022-06-30T04:30:54.671969+00:00 app[web.1]: 10.1.24.2 - - [30/Jun/2022:04:30:54 +0000] "GET /public/signin.php HTTP/1.1" 500 - "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36
該当のソースコード
フォルダ構成
thdocs/evenosche ├─classes │ ├─dao │ └─entity ├─function ├─javascripts ├─public ├─stylesheet │ ├─components │ ├─projects │ └─utilities ├─templates └─vendor └─(省略)
public/signin.php
PHP
1<?php 2 3namespace LocalMyStudy\Evenosche\exec; 4 5require_once __DIR__ . "/../vendor/autoload.php"; 6session_start(); 7 8use PDO; 9use PDOException; 10use Twig\Loader\FilesystemLoader; 11use Twig\Environment; 12use LocalMyStudy\Evenosche\Classes\Conf; 13use LocalMyStudy\Evenosche\Classes\Dao\UserDAO; 14 15$loader = new FilesystemLoader( __DIR__ ."/../templates"); 16$twig = new Environment($loader); 17 18$templatePath = "signin.html"; 19$assign = []; 20 21 22if(isset($_POST["btn"]) && $_POST["btn"] == "back"){ 23 header("Location:./signup.php"); 24 exit; 25} 26 27try{ 28 $db = new PDO(Conf::DB_DNS,Conf::DB_USERNAME,Conf::DB_PASSWORD); 29 $userDAO = new UserDAO($db); //!!エラー発生個所!! 30 if(isset($_POST["btn"]) && $_POST["btn"] == "submit"){ 31 //登録ボタンを押した時ではない 32 //バリデーションチェック 33 $signInULoginId = $_POST["signInULoginId"]; 34 $signInUPass = $_POST["signInUPass"]; 35 $signInULoginId = str_replace(" "," ",$signInULoginId); 36 $signInUPass = str_replace(" "," ",$signInUPass); 37 38 $validationMsgs = []; 39 40 if(empty($signInULoginId)){ 41 $validationMsgs["error"] = "ログインIDの入力は必須です。"; 42 } 43 if(empty($signInUPass)){ 44 $validationMsgs["error"] = "パスワードの入力は必須です。"; 45 } 46 47 //ユーザーIDの存在チェック 48 $user = $userDAO->findByLoginId($signInULoginId); 49 if(empty($user)){ 50 $validationMsgs["error"] = "ログインID又はパスワードが間違っています"; 51 } 52 53 if(empty($validationMsgs)){ 54 //パスワードチェック 55 $uPass = $signInUPass; 56 for($i=0; $i<$user->getUStretch(); $i++){ 57 $uPass = md5($user->getUSalt().$uPass); 58 } 59 if($uPass !== $user->getUnHashedPass()){ 60 $validationMsgs["error"] = "ログインID又はパスワードが間違っています"; 61 } 62 } 63 64 if(empty($validationMsgs)){ 65 //バリデーションが空 66 $_SESSION["userId"] = $user->getUId(); 67 header("Location:./show_event_list.php"); 68 exit; 69 } 70 else{ 71 //バリデーションが空じゃない 72 $assign["validationMsgs"] = $validationMsgs; 73 $assign["loginId"] = $signInULoginId; 74 $assign["pass"] = $signInUPass; 75 } 76 } 77} 78catch(PDOException $ex){ 79 var_dump($ex); 80 echo "error"; 81 /* $assign["errorMsg"] = "DB接続に失敗しました"; 82 $templatePath = "error.html"; */ 83} 84finally{ 85 $db = null; 86} 87 88$html = $twig->render($templatePath,$assign); 89echo $html; 90 91?> 92
classes/entity/User.php
PHP
1<?php 2 3namespace LocalMyStudy\Evenosche\Classes\Entity; 4 5class User { 6 private ?int $uId = null; 7 private ?string $uLoginId = ""; 8 private ?string $uPass = ""; 9 private ?string $uName = ""; 10 private ?string $uSalt = ""; 11 private ?int $uStretch = null; 12 13 private ?string $unHashedPass = ""; 14 15 //以下アクセサメソッド 16 public function getUId(): ?int { 17 return $this->uId; 18 } 19 public function setUId(int $uId): void { 20 $this->uId = $uId; 21 } 22 public function getULoginId(): ?string { 23 return $this->uLoginId; 24 } 25 public function setULoginId(string $uLoginId): void { 26 $this->uLoginId = $uLoginId; 27 } 28 public function getUPass(): ?string { 29 return $this->uPass; 30 } 31 public function getUnHashedPass(): ?string { 32 return $this->unHashedPass; 33 } 34 public function setUPass(string $uPass): void { 35 //ハッシュ化していないパスワード 36 $this->unHashedPass = $uPass; 37 //ソルト生成 38 $this->uSalt = uniqid(); 39 //ストレッチ 40 $this->uStretch = mt_rand(10000,100000); 41 //パスワードハッシュ化 42 for($i=0; $i<$this->uStretch; $i++){ 43 $uPass = md5($this->uSalt.$uPass); 44 } 45 $this->uPass = $uPass; 46 } 47 public function getUName(): ?string { 48 return $this->uName; 49 } 50 public function setUName(string $uName): void { 51 $this->uName = $uName; 52 } 53 public function getUSalt(): ?string { 54 return $this->uSalt; 55 } 56 public function setUSalt(string $uSalt): void { 57 $this->uSalt = $uSalt; 58 } 59 public function getUStretch(): ?string { 60 return $this->uStretch; 61 } 62 public function setUStretch(string $uStretch): void { 63 $this->uStretch = $uStretch; 64 } 65} 66?>
classes/dao/UserDAO.php
PHP
1<?php 2 3namespace LocalMyStudy\Evenosche\Classes\Dao; 4 5use PDO; 6use LocalMyStudy\Evenosche\Classes\Entity\User; 7 8class UserDAO { 9 //DB接続オブジェクト 10 private $db; 11 //コンストラクタ 12 public function __construct(PDO $db) { 13 $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 14 $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 15 $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); 16 $this->db = $db; 17 } 18 19 //会員登録 20 public function insert(User $user): int { 21 $sqlInsert = "INSERT INTO users (u_login_id,u_pass,u_name,u_salt,u_stretch) VALUES (:u_login_id,:u_pass,:u_name,:u_salt,:u_stretch)"; 22 $stmt = $this->db->prepare($sqlInsert); 23 $stmt->bindValue(":u_login_id", $user->getULoginId(), PDO::PARAM_STR); 24 $stmt->bindValue(":u_pass", $user->getUPass(), PDO::PARAM_STR); 25 $stmt->bindValue(":u_name", $user->getUName(), PDO::PARAM_STR); 26 $stmt->bindValue(":u_salt", $user->getUSalt(), PDO::PARAM_INT); 27 $stmt->bindValue(":u_stretch", $user->getUStretch(), PDO::PARAM_STR); 28 $result = $stmt->execute(); 29 if($result) { 30 $dpId = $this->db->lastInsertId(); 31 } 32 else { 33 $dpId = -1; 34 } 35 return $dpId; 36 } 37 38 //ログインIDで検索し件数を取得 39 public function findByLoginId(string $ULoginId): ?User { 40 $sql = "SELECT * FROM users WHERE u_login_id = :u_login_id"; 41 $stmt = $this->db->prepare($sql); 42 $stmt->bindValue(":u_login_id", $ULoginId, PDO::PARAM_STR); 43 $result = $stmt->execute(); 44 45 $user = null; 46 if($result && $row = $stmt->fetch()){ 47 $uId = $row["u_id"]; 48 $uLoginId = $row["u_login_id"]; 49 $uPass = $row["u_pass"]; 50 $uName = $row["u_name"]; 51 $uSalt = $row["u_salt"]; 52 $uStretch = $row["u_stretch"]; 53 54 $user = new User(); 55 $user->setUId($uId); 56 $user->setULoginId($uLoginId); 57 $user->setUPass($uPass); 58 $user->setUName($uName); 59 $user->setUSalt($uSalt); 60 $user->setUStretch($uStretch); 61 } 62 return $user; 63 } 64} 65?>
class/Conf.php
PHP
1<?php 2 3namespace LocalMyStudy\Evenosche\Classes; 4 5class Conf{ 6 const DB_DNS = "mysql:host=???;dbname=???;charset=utf8"; 7 const DB_USERNAME = "???"; 8 const DB_PASSWORD = "???"; 9} 10?>
composer.json
JSON
1{ 2 "require": { 3 "twig/twig": "^3.4", 4 "doctrine/dbal": "~2.3" 5 }, 6 "autoload":{ 7 "psr-4":{ 8 "LocalMyStudy\\Evenosche\\Classes\\":"classes/" 9 } 10 } 11}
試したこと
ルートがHerokuは「htdocs」ではないのかも…?と思い、
"LocalMyStudy\Evenosche\Classes\":"classes/"
→"Evenosche\Classes\":"classes/"
に変更してみたものの、うまくいかず…。
(エラーはパスの部分以外同様でclassが読み込めませんという内容でした。)
あと、謎にconfクラスは読みこめているみたいです…。
補足情報(FW/ツールのバージョンなど)
PHP 7.4.10
Composer version 2.2.5
XAMPP for Windows 7.4.10
あなたの回答
tips
プレビュー