質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.86%

パーフェクトPHP 第8章 ミニブログでのエラー解決

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 633

Hirakin3

score 31

 前提・実現したいこと

書籍パーフェクトPHPのミニブログの写経で

メンバの呼び出しに関するエラーという認識ですが解決できていません。

アドバイスを頂ければ幸いです。

 発生している問題・エラーメッセージ

Fatal error: Uncaught Error: Call to a member function getBaseUrl() on null in C:\xampp\htdocs\practice\mini-blog\core\Controller.php:47 Stack trace: #0 C:\xampp\htdocs\practice\mini-blog\controllers\AccountController.php(93): Controller->render(Array) #1 C:\xampp\htdocs\practice\mini-blog\core\Controller.php(38): AccountController->signinAction(Array) #2 C:\xampp\htdocs\practice\mini-blog\core\Application.php(122): Controller->run('signin', Array) #3 C:\xampp\htdocs\practice\mini-blog\core\Application.php(107): Application->runAction('account', 'signin') #4 C:\xampp\htdocs\practice\mini-blog\web\index_dev.php(7): Application->run() #5 {main} thrown in C:\xampp\htdocs\practice\mini-blog\core\Controller.php on line 47

 該当のソースコード

 Controller.php

<?php

abstract class Controller
{
    protected $controller_name;
    protected $action_name;
    protected $application;
    protected $request;
    protected $response;
    protected $session;
    protected $db_manager;
    protected $auth_actions = [];

    public function __construct($application)
    {
        $this->controller_name = strtolower(substr(get_class($this), 0,-10));

        $this->application = $application;
        $this->requeest    = $application->getRequest();
        $this->response    = $application->getResponse();
        $this->session     = $application->getSession();
        $this->db_manager  = $application->getDbManager();
    }

    public function run($action, $params = [])
    {
        $this->action_name = $action;

        $action_method = $action . 'Action';
        if(!method_exists($this, $action_method)){
            $this->forward404();
        }

        if ($this->needsAuthentication($action) && !$this->session->isAuthenticated()){
            throw new UnauthorizedActionException();
        }

        $content = $this->$action_method($params);

        return $content;
    }

    protected function render($variables = [], $template = null, $layout = 'layout')
    {
        $defaults = [
            'request'  => $this->request,
            'base_url' => $this->request->getBaseUrl(),
            'session'  => $this->session,
        ];

        $view = new View($this->application->getViewDir(), $defaults);

        if (is_null($template)){
            $template = $this->action_name;
        }

        $path = $this->controller_name . '/' . $template;

        return $view->render($path, $variables, $layout);
    }

    protected function forward404()
    {
        throw new HttpNotFoundException('Forwarded 404 page from '
            . $this->controller_name . '/' . $this->action_name);
    }

    protected function redirect($url)
    {
        If (!preg_match('#https?://#', $url)){
            $protocol = $this->request->isSsl() ? 'https://' : 'http://';
            $host = $this->request->getHost();
            $base_url = $this->request->getBaseUrl();

            $url = $protocol . $host . $base_url . $url;
        }

        $this->response->setStatusCode(302, 'Found');
        $this->response->setHttpHeader('Location', $url);
    }

    protected function generateCsrfToken($form_name)
    {
        $key = 'csrf_tokens/' . $form_name;
        $tokens = $this->session->get($key, []);
        if (count($tokens) >= 10) {
            array_shift($tokens);
        }

        $token = sha1($form_name . session_id() . microtime());
        $tokens[] = $token;

        $this->session->set($key, $tokens);

        return $token;
    }

    protected function checkCsrfToken($form_name, $token)
    {
        $key = 'csrf_tokens/' . $form_name;
        $tokens = $this->session->get($key, []);

        if (false !== ($pos = array_search($token, $tokens, true))){
            unset($tokens[$pos]);
            $this->session->set($key, $tokens);

            return true;
        }

        return false;
    }

    protected function needsAuthentication($action)
    {
        if ($this->auth_actions === true
            || (is_array($this->auth_actions) && in_array($action, $this->auth_actions))
        ){
            return true;
        }

        return false;
    }

}

 Request.php

<?php

class Request
{
    public function isPost()
    {
        if($_SERVER['REQUEST_METHOD'] === 'POST'){
            return true;
        }

        return false;
    }

    public function getGet($name, $default = null)
    {
        if(isset($_GET[$name])){
            return $_GET[$name];
        }

        return $default;
    }

    public function getPost($name, $default = null)
    {
        if(isset($_POST[$name])){
            return $_POST[$name];
        }

        return $default;
    }

    public function getHost()
    {
        if(!empty($_SERVER['HTTP_HOST'])){
            return $_SERVER['HTTP_HOST'];
        }

        return $_SERVER['SEVER_NAME'];
    }

    public function isSsl()
    {
        if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on'){
            return true;
        }
        return false;
    }

    public function getRequestUri()
    {
        return $_SERVER['REQUEST_URI'];
    }

    public function getBaseUrl()
    {
        $script_name = $_SERVER['SCRIPT_NAME'];

        $request_uri = $this->getRequestUri();

        if(0 === strpos($request_uri, $script_name)){
            return $script_name;
        } else if (0 === strpos ($request_uri, dirname ($script_name))){
            return rtrim(dirname($script_name), '/');
        }

        return '';
    }

    public function getPathInfo()
    {
        $base_url = $this->getBaseUrl();
        $request_uri = $this->getRequestUri();

        if (false !== ($pos = strpos($request_uri, '?'))){
            $request_uri = substr($request_uri, 0, $pos);
        }

        $path_info = (string)substr($request_uri, strlen($base_url));

        return $path_info;
    }
}

 補足情報(FW/ツールのバージョンなど)

  • PHP ver.7
  • Windows
  • XAMMP環境
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

エラー内容としては、存在しないオブジェクト上でメソッドを叩いてる

というエラーで、原因はコンストラクタ内の

$this->requeest

のタイプミスと思われます

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/09 12:15

    初歩的なミスですが「存在しないオブジェクト上でメソッド」という点に気づいていなかったので助かりました。

    仕組みから再度確認するようにします。
    ご指摘ありがとうございました。

    キャンセル

  • 2018/10/09 14:01

    文法エラーやタイプミスを検出できるまっとうなエディタを使えば防げます。
    生産性の高いエディタを使うところまでが、環境構築ですよ。

    キャンセル

  • 2018/10/18 21:53

    アドバイスへの返信遅くなりました。NetBeansで一部機能が有効になっておらず設定行いました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.86%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る