中卒派遣30代ブサメン童貞のブログ

みんなが存在に疑問を感じている「中卒、派遣、30歳超えのブサメン童貞」が実際に生息し、そして「どうやって生きてるか」を晒していくブログ

まだMAMPで消耗してるの?

macOS + PHP + Apache

突然ですが、VirtualBoxを少し離れてみます。僕は頭が悪いのでGUIでグリグリやれないと、なんかしっくりこないんです。きょうは上司に言っても理解されないことばランキング1位「なんかしっくりこない」を活用してきたいと思います。

上司「みんなこの環境使ってるからさ〜、◯◯くんも使ってみてよ。情報共有もセキュリティ面も楽だしさ〜(本音)」
ぼく「あー、なんか1回試してみたんすけど、なんかしっくりこないんすよね。」
上司「そんなこと言わないでよ〜(契約更新なしね)」
ぼく「あははー(契約更新の話が出る前に、こっちから辞めてやる)」

以前のエントリにも書いたとおり、最近のMacにはPHPApacheも最初から入っているので、これを使わない手はありません。確かにCyberduck等で見えるとはいえ、見慣れているFinderから視覚的にファイルの動きが見られること、それからファイル共有をあまり深く考えなくてもいいというのが頭の悪い僕には魅力的です。

vim恐怖症

「怖いよー、なんか思っているとおりに動かないよー。viとvimの違いがわからないよー」と思っている人も、これだけ覚えてしまえば安心。「あ、やべ」と思ったら、保存しなけりゃいいんだよ!

コマンド 動作
:w 上書き保存
:q 終了
:wq 保存して終了
:q! 保存しないで終了
i インサートモードへ移行
ESC コマンドモードへ戻る

PHPを動かす

WebサーバでPHPを動かせるようにします。環境は「柴」でメール検索していることで有名なmacOS High Sierra。エディタはなんでもいいんですが、できる男を演出するためにvimにします、あえてね。まずはターミナルを立ち上げ、以下のコマンドを打ち込んでhttpd.confを編集します。編集する際はバックアップを忘れずに。死にます。

$ sudo vim /etc/apache2/httpd.conf

httpd.conf内の、

#LoadModule php7_module libexec/apache2/libphp7.so

コメントアウトを外して、

LoadModule php7_module libexec/apache2/libphp7.so

PHPのバージョンによって75だったりしていると思いますが、たぶんやることは同じです。これでWebサーバでPHPが動くと思います。ただ、動くには動くんですが、今のままだといろいろと面倒なので、ついでにドキュメントルートも変更します。

同じくhttpd.conf内の、

DocumentRoot "/Library/WebServer/Documents"
<Directory "/Library/WebServer/Documents">

ここの/Library/WebServer/Documentsを設定したいパスに書き直します。例えば/Users/USERNAME/Websites/みたいな感じに。あとは、このディレクトリに適当な内容のindex.phpを置いて、Apacheを起動します。

$ sudo apachectl start

起動したらブラウザでhttp://localhost/と打ち込んであげれば、上記のディレクトリに入れたindex.phpが表示されているはずです。

ただし、OSにバンドルされているものを特に工夫もなく使っているので、バージョンが変わるとたぶん動きません。共有させたりデータベースを使うことになったら、それはそのときにまた考えます。

多次元連想配列は初心者には難しい

json_decode() をしよう

フォームのデザインをしようと思ってBootstrapを調べていたんですが、普通にCSSを書くよりわかりにくくないすかね。いや、CSSを書いたことがないから、よくわかってないまま言ってんすけどね。グリッドとかの理解からスタートするところで、もう思考回路がショート寸前。でも、世の中で受け入れられている以上、使いやすいんでしょうね。PHPが動いたら、ちゃんと調べます。

さて、遠い昔の前回はAPIJSON形式でPOST送信することができた(と思う)ので、ちゃんと送信できていればAPI側からJSON形式のデータが戻っているはずです。まずはそれをPHPで扱えるようにします。

<?php
// JSON形式の戻り値を連想配列で取得
$res_json = json_decode($result, true);

引数をtrueにしないと連想配列の形式になりません。

美容整形

さて、難関はここからです。僕の耳には入りませんが、JSONはコンピュータにも人の目にも、ある程度やさしいと言われています。が、そうはいっても整形されていないと何がなんだかわかりません。頭の悪い僕にとっては値を取り出すどころの話ではありません。まず、どこに何が書いてあるのかを把握するだけで数年の経過を覚悟しないといけません。

しかし、そこは先人の知恵。オンライン上でJSONの整形と構文チェックができるサービスを見つけてしまいました。それがJSON Pretty Linter Ver3先生です。この世の中は天才と神が多すぎる。 lab.syncer.jp

ちなみにDocumentationにはAPIから返ってくる文章のサンプルとしてこう書かれています。こんな短い文章でも僕の脳は拒否の姿勢を崩しません。ある意味、立派です。

{"request_id":"record001","info_filter":"form","word_list":[[["日本語"],["を"],["分析"],["し"],["ます"]]]}

しかし、JSON Pretty Linter Ver3先生の手にかかれば、こんなものは朝飯前。見とけよ見とけよ〜。

{
    "request_id": "record001",
    "info_filter": "form",
    "word_list": [
        [
            [
                "日本語"
            ],
            [
                "を"
            ],
            [
                "分析"
            ],
            [
                "し"
            ],
            [
                "ます"
            ]
        ]
    ]
}

うーん、まー、なんだ。値が少なすぎて逆に見づらくなってしまった感がありますが、もっともっと複雑な配列になったとき、先生の本領が発揮されます。はっきりわかんだね。次はここから欲しい値を取り出す作業です。

タイピング技能検定を取りました

きのうは500mlの第三のビールを飲んだら、ブログを更新する前に寝てしまいました。歳を重ねるごとに酒に弱くなっています。

さて、なんの役に立つのか全くわからない資格ランキングの上位常連、イータイピングのタイピング技能検定というものを取得してみました。2級です。受験料は5400円。高すぎる。 web.e-typing.ne.jp

某社に派遣登録に行ったら面談でやらされて「あー、こんなのもあんねんやな」と思ってから数年、ついにその資格を取得してしまいました。ちなみに、派遣登録に行くとOffice系ソフトと並んでやらされる確率の筆頭候補のタイピングですが、実務でタイピング速度を求められた経験は皆無です。手元を見ないで、ある程度のショートカットキーを使えることのほうが遥かに重要な気がします。

もっと高い級位が取れたかもしれませんが、この資格、高い級位を書くと逆に地雷になりませんか?「タイピング技能検定特級ってwwwwwwwwロマンスカーwwwwwwwwwww」みたいな。実際、どんなに超速タイピングを披露したとしても「さすが特級wwwwwwwwwテラハヤスwwwwwwwwwwwwww」みたいな。僕みたいな自分に自信のない人は被害妄想が捗ります。

それにつけても cURL

変数をセット

外出する前にはバッグを用意します。バッグの中にはクリアファイルと財布が入っています。クリアファイルの中には書類が何枚、財布の中にはコンドー……というわけで、何をするにせよ準備が大事。ちゃんと体は洗った?きょうのform.phpです。

<?php

$ma = "";

// POSTされたデータか確認
if ($_SERVER['REQUEST_METHOD'] === "POST") {
  $ma = $_POST['ma'];
}

// リクエスト先URL
$url = "https://corevo/goolab/api?apikey=";

// APIキーのセット
$key = "a1b2c3d4e5f6g7h8u9j0";

// 送信するデータの準備
$postdata = array(
  'sentence' => $ma
);

まずはPOST経由のアクセスではないときにNoticeエラーを出させないための変数宣言を行います。どうせ配列が入ることを前提にした変数なので$ma = array();も試してみたのですが、エラーを吐くことなく普通に動きました。ただ、あまり目にしません。なぜ?教えてエロい人。

続いてのリクエスト先URLとAPIキーはcorevo APIのDocumentationから拾ってきて、それぞれを変数に代入します。ここまでは頭の悪い僕でもおおよそ理解できます。ちなみに、当然ですが上記のURLとAPIキーはフェイクです。ファーwww

そして送信するデータを配列で用意します。キーはパラメータ名。今回は必須のパラメータがsentenceだけ、ほかは省略すると全指定されたことになるので、とりあえず都合のいいように書きます。どうせあたしは都合のいい女よ。

cURL を使う

通常はPHPでHTTPリクエストを扱う場合file_get_contents()を使うことが多いらしく、BOOKOFFで立ち読みしたバリバリに貼り付いたPHP教本も、そのやり方でXMLを取得していました。が、cURLのほうがパフォーマンスが高いとか、細かい設定をするには向いているとか、昨今ではcURL勢力のステマPHP界隈で猛威をふるっているようです。事なかれ主義の僕としては、おとなしく右に倣うことにします。

cURLの基本的な流れは以下のようになるらしいです。

curl_init()により cURL セッションを初期化
curl_setopt() により転送時のオプションを設定
curl_exec() により転送を実行
curl_close() によりセッションを終了する

PHP: 基本的な curl の使用法 - Manual

上記の流れをそのままトレスしてみます。今回は転送時のオプションを複数設定するのでcurl_setopt_array()を使いますが、curl_setopt()で個別に書いても動きます。何を隠そう、最初はひとつひとつ書いていました。

<?php

// CURLセッションの初期化
$ch = curl_init();

// CURLオプションの設定
$options = array (
  // 取得するURL
  CURLOPT_URL => $url .$key,

  // リクエストヘッダをJSONに設定
  CURLOPT_HTTPHEADER => array ("Content-Type: application/json"),

  // HTTPリクエストをPOSTに設定
  CURLOPT_CUSTOMREQUEST => "POST",

  // POSTするデータ
  CURLOPT_POSTFIELDS => json_encode($postdata),

  // trueでcurl_exec()の返り値を文字列で返す
  CURLOPT_RETURNTRANSFER => true,
);

curl_setopt_array($ch, $options);

// 転送を実行し変数に代入
$result = curl_exec($ch);

// CURL処理を終了
curl_close($ch);

基本的にコメントのまんまです。json_encode()API側に渡したいデータをJSONエンコードCURLOPT_POSTFIELDSはURLエンコードされた文字列を渡さないとapplication/x-www-form-urlencodedになりません。またcurl_exec()はブール値で返ってくるのでtrueを指定して文字列で受け取るようにします。

コロン構文 の便利さを知る

ラジオボタンチェックボックス

あれからinput type="radio"input type="checkbox"も使って、あらかじめ拡張しようと思っているところまで記述してみました。途中で追加しようとすると、きっと今まで動いていたものまで動かなくなるので、そうならないための予防線です。というか、絶対に動かなくなりますって。今はdisabled属性にしていますが、恥ずかしいので実装できるまでコメントアウトにするかもしれません。

<form action="" method="POST">
  <h2>APIを選択</h2>
  <p>
    <input type="radio" name="" value="corevo" checked>corevo API
    <input type="radio" name="" value="yahoo" disabled>Yahoo! API
  </p>
  <h2>オプションを選択</h2>
  <p>
    <label><input type="checkbox" name="" checked>形態素解析</label>
    <label><input type="checkbox" name="" disabled>固有表現抽出</label>
  </p>
  <h2>文章を入力</h2>
  <p><input type="text" name="ma" value="文章を入力"></p>
  <p><input type="submit" value="解析"></p>
</form>

現状のform.phpはこんな感じです。name属性の値は配列になるはずなんですが、全くわかっていないのでブランクにしています。わからないばかり言ってんな、こいつ。

コロン構文

ドットインストールのPHP入門ではforeach()のときにチラッとふれられていたコロン構文ですが、やっとHTMLの中に埋め込むときにすっきり書けるの意味と使い勝手がわかってきました。まずは、きのうまでのform.php

<h2>出力するテスト</h2>
<?php echo htmlspecialchars($ma, ENT_QUOTES, "utf-8"); ?>

セキュリティ面で少し処理をおこなっていますが、基本的に$maを書き出す命令です。それを、

<?php if (isset($_POST['ma'])) : ?>
  <h2>出力するテスト</h2>
  <?php echo htmlspecialchars($ma, ENT_QUOTES, "utf-8"); ?>
<?php endif; ?>

このように記述するとif文のコロン構文を用いて、配列$_POST['ma']trueのときに$maを書き出すようになります。まだ慣れていないですが、確かに便利ですし、何より視認性が違います。

フォームを作る

はじめてのPHP

引き続きアスラドットインストール先生にお世話になっています。解析したい文字列はフォームで取得するのでHTML入門でform要素について、PHP入門で配列の仕様とif文、foreach文、$_SERVER$_POSThtmlspecialchars()の動画を視聴。

そうすると、form.phpが作れます。

<?php

$ma = "";

// POSTされたデータか確認
if ($_SERVER['REQUEST_METHOD'] === "POST") {
  $ma = $_POST['ma'];
}

?>
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>フォームのテスト</title>
</head>
<body>
  <h1>フォームのテスト</h1>
  <form action="" method="POST">
    <input type="text" name="ma" value="解析したい文章を入力">
    <input type="submit" value="送信">
  </form>
  <h2>出力するテスト</h2>
  <?php echo htmlspecialchars($ma, ENT_QUOTES, "utf-8"); ?>
</body>
</html>

作れちゃいました。これで履歴書に「HTMLとPHPができます」って書けます!ドットインストール先生、ありがとう!!ちなみに、$_SERVER["REQUEST_METHOD"] === "POST"の意味がよくわからなかったのですが、ググったらわかりやすい説明があるページを見つけました。

フォームなどでサンクスページに重要な処理を記述していた場合、ダイレクトにサンクスページにアクセスされたら不都合もありますね。そこで、フォームからPOST経由でアクセスされたかを確認する方法です。

PHP($_SERVER)サーバー変数一覧と実用例

なるほど。そういうことなら、ある意味では決まり文句みたいなものかもしれません。今回はPOST送信後に別URLに遷移するわけではないので、「ブックマークなどから最初にアクセスされた場合」と理解してもよさそうです。ついでに、フォームからPOST送信された中身が空だった場合の分岐も考えてみます。

<?php

$ma = "";

// POSTされたデータか確認
if ($_SERVER['REQUEST_METHOD'] === "POST") {
  // maの中身の確認
  if ($_POST['ma'] === "") {
    $ma = "空だゾ?";
  } else {
    $ma = $_POST['ma'];
  }
} else {
  $ma = "ようこそ!";
}

?>

こうするとPOST経由でアクセスしてない場合は「ようこそ!」、POST送信された中身がない場合は「空だゾ?」を変数に代入してくれます。実際に使うかどうかは別として、挙動の確認のために書いてみました。

isset()が動かないよ

ちなみに、はじめはisset()で中身の確認をしようと思っていたのですが、何回やっても、何回やっても、フォームの中身が空なのにtrueが返ってきます。嘘だッ!!!1時間くらい悩んで、さらに1時間くらいかけて調べた結果、またもや天才的にわかりやすい説明を発見。

$_POST変数はarray配列のため、POST送信されていないときは、要素が0個のarray配列となり、その場合、isset関数ではnullではないのでtrueとなり、要素が1個以上の場合もtrueとなってしまいます。

PHPの入力値確認ではなぜisset関数ではなくempty関数を使うのか - nicson (@_@) IT漂流記

eyeからscale。isset()のことを単純に中身がある・なしの判断をするものだと思い込んでしまったことからはじまったミスでした。君のこと、誤解してたみたい。今でも微妙にしっくりきていないのですが、要素が0個の配列というのはとても重要らしく、ググるといろいろな言語で要素=サイズ=長さが0の配列についての説明があります。ビールのように、大人になったらわかるのかも。

開発環境を整える

PHP でやる

「やりたいこと」は決まったのですが、「何でそれをやるのか」が全く決まっていませんでした。というかHTMLすら知らないので、そのつど後追いで調べることになり「あ、こんなのも必要なのか。困るんだよなあ、こういうことされると」になることの連続です。しかたないね。いろいろと調べてみた結果、やっぱり「かわいい=正義」、「情報量が多い=正義」、「かわいい=情報量が多い」ということで、PHPでやろうと思います。

まず僕のPCはiMac(Late 2012)なので、PHPApacheも入っています。そもそもビルトインウェブサーバーもあります。なので、わざわざMAMPなんて使いません。おっかないし、自信ないし、そういうのは頭のいい人に任せます。最初から用意されているもの、ビールとお通しだけでお腹いっぱいになっちゃうんで。おやっさん、この塩辛うまいね。

ドットインストール先生

さて、「やりたいこと」と「その手段」がはっきりしたので開発環境を整えます。昨今の世の中には本当にすごい人がいるもんで、僕が選んだのはこのしじみ習慣ドットインストール。ここでやっていることを全部トレスしました。学校なんて行かなくてもええやん。先生、一生ついていきます。先生のためなら童貞を棄ててもいい。ちなみに早口、超早口。老人にはおすすめできない超高速ピストン仕様。

まずはAtom入門、エディタがないとイライラとムラムラが蓄積されて爆発するだけです。そしてローカル開発環境の構築 [macOS編]、これで開発環境を作ります。なんて簡単なの⁉︎ただ個人的にVagrantの意味が全くもってよくわからなかったので、それは別ページを参照しました。

dev.classmethod.jp

お恥ずかしい話ですが、上記を読んでも完璧には理解できていません。それでも「手を動かしていけばわかるだろう」という精神で、とりあえず細かい理解は無視して進めていきます。