PHP <条件分岐でのincludeとURLからのタイトル取得>

#はじめに
最近はPHPについて学習しています。
ここ一ヶ月の勉強で学んだことを使用しながら、簡単なプログラムを作ってみました。
セキュリティ関係はほとんど考慮していません。ある程度のセキュリティについては[こちらの記事](https://qiita.com/vber_program/items/5f47dd59dcbd671aa17b)で説明しています。

#作成した機能の説明

初期画面は以下の通り。
GETを使用したページ遷移を行いたい。また入力したURLからそのサイトの情報を一部取得したい(ここではtitleタグ取得する)。
<img width="415" alt="スクリーンショット 2019-11-30 20.45.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386463/ee363a2e-f61f-94bf-fc0b-4e7fbdf9692a.png">
TopPage、MyPage、送信を押した場合の画面は以下の通り。
URLから取得したタイトルとそのURLをリンクとして表示する。またTopPageを押した場合はQiitaのトップページを、MyPageを押した場合は自分のMyPageを取得している。
<img width="585" alt="スクリーンショット 2019-11-30 20.45.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386463/66c3d9cb-c3f4-2525-bfbb-6d86b095db03.png">
#コード

先に上のプログラムのコードを載せておきます。

```php:main.php
<html>
 <head>
  <title>PHP Test</title>
 </head>
 <body>
 <h1>Qiitaのページ検索</h1>
<p>↓にincludeしたい</p>
<?php 
    if(!isset($_GET['title']) and !isset($_GET['pageid'])){
        include 'search.php';
    } else {
        include 'result.php';
    }
?>
<p>↑にincludeしたい</p>
 </body>
</html>
```

```html:search.php
<form name = "form1" action = "main.php" method = "GET">

    <!-- TopPage -->
    <button type="submit" name="pageid" value=2>TopPage</button>
    <br/>

    <!-- MyPage -->
    <button type="submit" name="pageid" value=1>MyPage</button>
    <br/>

    <!-- 記事検索(入力チェックあり) -->
    <input type = "text" name ="title" pattern="^https://qiita.com{1}[a-zA-Z0-9!-/:-@¥[-`{-~]*$">
    <br/>
    <input id="send" value="送信" type="submit">
</form>
```

```php:result.php
<?php

    // エラー確認用
    ini_set('display_errors', "On");
    ini_set('error_reporting', E_ALL);

    //タイトルを取得したいURL
    $url = '';

    // 表示するテキスト
    $text = '';
    $urlText = '';

    if(isset($_GET['title'])){
        //タイトルを取得したいURL
        $url = $_GET["title"];
    }

    if(isset($_GET['pageid'])){

        $pageid = $_GET['pageid'];

        // urlを設定
        switch ($pageid) {
            case 1:
                $url = 'https://qiita.com/vber_program';
                break;
            case 2:
                $url = 'https://qiita.com/';
                break;
        }  
    }

    if($url==''){
        echo "入力が空です<br>";
        return;
    }

    if(!preg_match("#^https://qiita.com+[a-zA-Z0-9!-/:-@¥[-`{-~]*$#",$url)){
        //urlがQiita以外のものは不正なページとして扱う
        echo "不正なページです。<br>";
        return;
    }

    //ソースの取得
    $source = @file_get_contents($url);

    //取得できたかどうかを判定
    if($source){
        //取得できたのでページは存在する
        //文字コードをUTF-8に変換し、正規表現でタイトルを抽出
        if (preg_match('/<title>(.*?)<\/title>/i', 
                        mb_convert_encoding($source, 'UTF-8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS'), 
                        $result)) {
            $urlText = $result[1];
            $urlText = str_replace("- Qiita", "", $urlText);

            //URL置換
            $pattern = '(https?://[-_.!~*\'()a-zA-Z0-9;/?:@&=+$,%#]+)';
            $replacement = '<a href="\1" target="_blank">\1</a>';
            $text = mb_ereg_replace($pattern, $replacement, htmlspecialchars($url));
        }
    }else{
        //取得できなかったのでページは存在しない
        $text = "ページは存在しません";
    }

    echo $urlText."<br>";
    echo $text."<br>";
?>

<a href="main.php" >前のページに戻る</a>
```

#注意した点と簡単な解説

##条件分岐によるinclude
[main.php]
純粋にIF文を使うだけでした。
GETで値を取得していなければ「検索画面のsearch.php」を表示し、GETに値が入っていれば「結果表示画面のresult.php」を表示させています。

##正規表現チェック
[search.php , result.php]
入力画面とPHPの処理の両方に入れています。今回はQiitaのURL以外は弾くようにしています。
またtitleタグ内を取得する際にも使用しています。

##file_get_contents
[result.php]
入力したURLのソースを取得しています。失敗した場合にはFalseを返すのでIF文で判断します。

##preg_match
[result.php]
正規表現を使用して「file_get_contents」で取得したソースの中からtitleタグ内の情報を検索しています。

##mb_ereg_replace
[result.php]
正規表現を使用した文字置換。入力した値をURLに変換する際に使用しました。
また「htmlspecialchars」を使用して特殊文字をHTMLエンティティに変換しています。

##return
[result.php]
exitを使用して処理を抜けてしまうと、それ以降の処理(今回の場合は「↑にincludeしたい」を表示する部分)が中断されてしまいます。そのためreturnを使用して処理を抜けるようにしました。

#おわりに
今回使用した関数でわかりにくい部分があれば、[公式サイト](https://www.php.net/)で調べてみて下さい。
多分もっといい書き方があるはず……。

#参考にさせて頂いたサイト様
[PHP公式サイト](https://www.php.net/)

[PHPで指定したURLのタイトルタグの中身を取得する方法](https://otapps.net/archives/305)

[基本的な正規表現の使い方](https://qiita.com/AquaMeria/items/cf22ba6750a3812f6566)

[マコトのおもちゃ箱　～ぼへぼへ自営業者の技術メモ～](http://piyopiyocs.blog115.fc2.com/blog-entry-637.html)

[PHPのincludeでGETのパラメーター（引数）の渡し方]
(https://www.futaego.com/2018/php%E3%81%AEinclude%E3%81%A7get%E3%81%AE%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%83%BC%EF%BC%88%E5%BC%95%E6%95%B0%EF%BC%89%E3%81%AE%E6%B8%A1%E3%81%97%E6%96%B9/)

ありがとうございました！