20200223のPHPに関する記事は11件です。

publicとprivate、ゲッターとセッターについて

カプセル化とは?

カプセル化とは、クラスのプロパティとメソッドへのアクセスを制限すること。
publicとprivateを用いて定義する。

privateとpublic

クラスの外部からアクセスできるようにするには「public」を、アクセスできないようにするには「private」を用いて定義する。
プロパティは基本的にアクセス権をprivateにする。

class Menu {
  private $name;
}

$fruits = new Menu('apple');
echo $fruits->name;  // $nameがprivateのためエラーとなる。

ゲッターとは??

上記のように、privateにするとプロパティの値をクラスの外から取り出すことができなくなる。
そのため、プロパティの値を返すだけのメソッドを定義する必要がある。
このような、プロパティの値を返すだけのメソッドを特に「ゲッター」という。
ゲッターは「getプロパティ名」のように命名するのが一般的である。

class Menu {
  private $name;

  public function __construct($name) {
    $this->name = $name; // class内なのでこの書き方でアクセスができる
  }
  public function getName() {
    return $this->name; // class内なのでこの書き方でアクセスができる
  }
}

$fruits = new Menu('apple');
echo $fruits->getName();

セッターとは??

プロパティのアクセス権をprivateにするとプロパティの値をクラスの外から変更できなくなる。
そのため、プロパティの値を変更するメソッドを定義する必要がある。
このような、プロパティの値を変更するメソッドを特に「セッター」という。
セッターは「setプロパティ名」のように命名するのが一般的である。

class Menu {
  private $fruitsCount;

  public function setFruitsCount($fruitsCount) {
    $this->fruitsCount= $fruitsCount; 
  }
}

$fruits = new Menu('apple','strawberry','melon', ...);
$fruits->setFruitsCount(4); // セッターを用いて値をセット。
echo $fruits->setFruitsCount(); // 結果:4

$fruits->fruitsCount= 6;  // privateなので直接アクセスはできない!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

?【CakePHP2】バルクインサート失敗するときは対象カラムを確認する

環境

PHP 7.2.21
CakePHP 2.10.18

やりたいこと

ModelのinsertMulti()関数を使い、
配列の内容から複数件インサートを行う際に次のエラーが出たので対応した

error.log
SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens
error.log
                            [0] => `{schema名}`.`{table名}`
                            [1] => `id`, `hoge_fuga`, `foo_bar`, `toto`, `pippo`, `xyzzy`
                            [2] => Array
                                (
                                    [0] => Array
                                        (
                                            [id] => 0609045000
                                            [hoge_fuga] => 1123
                                            [new_column] => 1
                                            [foo_bar] => 202002
                                            [toto] => 2020-01-01
                                            [pippo] => 9999991
                                            [xyzzy] => Q-2
                                        )

やったこと

insertMultiの第2引数が対象カラムで第3引数がインサートする値配列
この2つにあるカラムが合っていないと↑のエラーが発生するので見直して修正する

HogeController.php
            $hogeItems[] = [
                'id'         => $id,
                'hoge_fuga'  => $hogeFuga,
                'new_column' => $newColumn, 
                'foo_bar'    => $fooBar,
                'toto'       => $toto,
                'pippo'      => $pippo,
                'xyzzy'      => $xyzzy,
            ];

            // ?それぞれのカラムが合致
            // バルクインサートする
            $this->HogeModel->getDataSource()->insertMulti(
                '{table名}',
                ['id' , 'hoge_fuga', 'new_column', 'foo_bar', 'toto', 'pippo', 'xyzzy'],
                $hogeItems
            );

            // ❌それぞれのカラムが揃っていない(↑のエラーの状態)
            // バルクインサートする
            $this->HogeModel->getDataSource()->insertMulti(
                '{table名}',
                ['id' , 'hoge_fuga', 'foo_bar', 'toto', 'pippo', 'xyzzy'],
                $hogeItems
            );
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Google Maps Static APIでサイズの異なるカスタムアイコンを配置する

動機付け

こちらのサイトを作りました。コロナウイルスに関する呟きを集計、可視化します。
corona-virus-trend - コロナウイルス情報を分析・可視化

呟かれている地名の頻度に応じて地図上にマッピングしたいと思ったのがきっかけです。
地図

前提条件

  • GCPでAPIキーを取得します。
  • サーバサイドスクリプト(PHP)が稼働するサーバを持っている必要があります。

ドキュメント

こちらに書いてあることがほぼ全てですが、いくつか詰まったところもありました。
Developer Guide  |  Maps Static API  |  Google Developers

カスタムアイコンのサイズ変更

サーバ上に画像を準備して以下の書式に合わせてURLを組み立てればいいのですが、自分はこのアイコンのサイズを地名のキーワードの頻度に合わせて変化させたかったのです。
markers=icon:URLofIcon|markerLocation

それぞれのサイズの画像を準備するという手もありますが、自分は動的にアイコンのサイズを変えることにしました。PHPを使っているのでこちらを参考にさせていただきました。ブラウザに直接出力しています。marker.pngは元画像、適宜パスを変えてください。
PHP: GDで画像のサイズ変更やサムネイル生成のやりかた - Qiita

resize.php
<?php
header('Content-Type: image/png');

/**
 * 画像のサイズを変形して保存する
 * @param string $srcPath
 * @param int $width
 * @param int $height
 */
function transform_image_size($srcPath, $width, $height)
{
    list($originalWidth, $originalHeight, $type) = getimagesize($srcPath);
    switch ($type) {
        case IMAGETYPE_JPEG:
            $source = imagecreatefromjpeg($srcPath);
            break;
        case IMAGETYPE_PNG:
            $source = imagecreatefrompng($srcPath);
            break;
        case IMAGETYPE_GIF:
            $source = imagecreatefromgif($srcPath);
            break;
        default:
            throw new RuntimeException("サポートしていない画像形式です: $type");
    }

    $canvas = imagecreatetruecolor($width, $height);
    //ブレンドモードを無効にする
    imagealphablending($canvas, false);
    //完全なアルファチャネル情報を保存するフラグをonにする
    imagesavealpha($canvas, true);

    imagecopyresampled($canvas, $source, 0, 0, 0, 0, $width, $height, $originalWidth, $originalHeight);

    imagepng($canvas, null);

    imagedestroy($source);
    imagedestroy($canvas);
}

$size = $_GET['size'];
transform_image_size('marker.png', $size, $size);
?>

カスタムアイコンの呼び出し数制限

呼び出すときに、時々カスタムアイコンではなくデフォルトアイコンになってどうしてだろうと数日悩みました。結局最初のドキュメントをチキンと読んでおくべきだったということです。一度の呼び出しで5種類までのカスタムアイコンしか呼べないということです。
Google Maps Static Map - Custom icons limit - Stack Overflow

Static Maps service allows up to five unique custom icons per request.
Note that each of these unique icons may be used multiple times within the static map.

ということで、アイコンの種類数を5種類に限定するロジックを組み込みました。最大値、最小値を取得してからその間の区間を3等分。以下のコードでは、$itemsに地名と頻度が格納されていて、Geocodingしてから地図を呼び出しています。

static_map.php
<?php
// put the data in the array
$data_arr = array();

foreach ($items as $address => $value) {
  // url encode the address
  $address = urlencode($address);

  // google map geocode api url
  $url = "https://maps.googleapis.com/maps/api/geocode/json?address={$address}&key=APIKEY";

  // get the json response
  $resp_json = file_get_contents($url);

  // decode the json
  $resp = json_decode($resp_json, true);

  // response status will be 'OK', if able to geocode given address 
    if($resp['status']=='OK'){

        // get the important data
        $lat = isset($resp['results'][0]['geometry']['location']['lat']) ? $resp['results'][0]['geometry']['location']['lat'] : "";
        $long = isset($resp['results'][0]['geometry']['location']['lng']) ? $resp['results'][0]['geometry']['location']['lng'] : "";
        $formatted_address = isset($resp['results'][0]['formatted_address']) ? $resp['results'][0]['formatted_address'] : "";

        // verify if data is complete
        if($lat && $long && $formatted_address){

            array_push(
                $data_arr, 
                    array($lat, 
                    $long, 
                    $formatted_address,
                    $value)
                );

       }
    }
}

// size mapping
$min = $data_arr[0][3];
$max = $data_arr[0][3];
foreach ($data_arr as $item) {
  if($min > $item[3] ) $min = $item[3];
  if($min < $item[3] ) $max = $item[3];
}

$range = $max - $min;
$portion = $range / 3;

// url building
$base_url = 'https://maps.googleapis.com/maps/api/staticmap?size=640x640&language=ja&maptype=roadmap&key=APIKEY';

$marker_array = array();
foreach ($data_arr as $item) {

  if($item[3] == $min)
    $size = $min;
  else if($item[3] > $min && $item[3] <= $min + $portion)
    $size = $min + $portion;
  else if($item[3] > $min + $portion && $item[3] <= $min + $portion * 2)
    $size = $min + $portion * 2;
  else if($item[3] > $min + $portion * 2 && $item[3] <= $min + $portion * 3)
    $size = $min + $portion * 3;
  else if($item[3] == $max)
    $size = $max;

  $marker_url = urldecode("http://corona-virus-trend.com/xxx/resize_icon.php?size={$size}");
  $marker_para = "markers=anchor:center|icon:{$marker_url}|{$item[2]}";
  array_push($marker_array, $marker_para);
}

$marker_para_str = join("&", $marker_array);
$map_url = $base_url . "&" . $marker_para_str;

print("<img src=\"$map_url\">");
?>

参考資料

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelのslot機能を使ってボタンの文言を変えて使い回す!

はじめに

Laravelのbladeでhtmlのコーディングを行っていると、「Vueのコンポーネントの様に中身だけ変えて使い回したい!って場面が多々出てくると思います。

そんな時にLaravelに元々あったsectionとは別にslotという機能がめちゃくちゃ感覚的に使えて良かったので説明していきます。

slot機能とは

まず、プロダクトの中で使い回すパーツをコンポーネントと呼びます。
例えば、こんな感じのボタンですかね。

スクリーンショット 2020-02-23 16.09.43.png

これをslot機能を使う事で、中の文言だけ変えて色々なところで使い回していきます。

slotの使い方

コンポーネント作成

まずコンポーネントを作っていきます。

変えていきたい部分を {{$slot}} としておきます。

views/button.blade.php
<button class="Button -fill -blue" type="button">
    <span class="Button__inner">
        <span class="Button__text">
            {{$slot}}
        </span>
    </span>
</button>

ちなみにボタンのscssはこんな感じですでに定義しています。

views/button.scss
.Button {
    @at-root {
        & {
            display: inline-flex;
            border: 0;
            border-radius: 3px;
            background-color:#ffffff;
            color: black;
            font-size: 14px;
            text-decoration: none;
            vertical-align: middle;

            &:hover {
                opacity: 0.8;
            }

            &.-fill {
                background: linear-gradient(to bottom, #fefefe 0%, #f3f5f7 100%);

                &.-blue {
                    background: linear-gradient(180deg, #1E4A91 0%, #193E79 100%);
                    color: $white;
                }

                &.-red {
                    background: linear-gradient(180deg, #F85359 0%, #DC151D 100%);
                    color: $white;
                }
            }

        .Button__inner {
            display: flex;
            align-items: center;
            justify-content: center;
            width: 100%;
            min-height: 32px;
            padding: 4px 15px;
            border: 1px solid $border-color;
            border-radius: 3px;
        }

        .Button__text {
            flex: 0 1 auto;
        }
    }
}

これにてボタンのコンポーネントはできました。

コンポーネントを呼び出す

先ほど作ったコンポーネントを呼び出していきます。

top.blade.php
@component('button')
    確認画面
@endcomponent

この様に('button')の部分にコンポーネント名。
@component@endconponentの間に{{$slot}}に入れたい文言を書きます。

ボタンを使い回す!

今後ボタンを使うときは、先ほどやった様に文言を指定して呼び出してあげるだけで簡単にできます。
top.blade.phpのみをいじる事で様々な文言のボタンを出してみましょう。

スクリーンショット 2020-02-23 16.51.34.png

top.blade.php
<div class="Button_group">
  @component('button')
    下書きを削除
  @endcomponent
  @component('button')
    下書きの保存して一覧の戻る
  @endcomponent
  @component('button')
    確認画面
  @endcomponent
</div>

<style>
.Button_group{
display:flex;
}
</style>

こんな感じで簡単に文言違いのボタンを複製できますね。
slotを使う事で、@includeだけでは実践できなかった、ちょっとした変更ができる様になります。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel プロジェクトに郵便番号データ、都道府県、市区町村データを簡単に作成する

Laravel プロジェクトに郵便番号データ、都道府県、市区町村データを簡単に作成するライブラリを作成しました。

Github
https://github.com/ShibuyaKosuke/laravel-postalcode-japan

laravel-postalcode-japan

郵便番号データを取り込んで住所マスタを作成します。

Install

composer require shibuyakosuke/laravel-postalcode-japan

Setup

マイグレーションを実行します。

php artisan migrate

postal_codes, cities, prefectures テーブルが作成されます。

php artisan postalcode:update

を実行すると、自動的に郵便番号データをダウンロードし、
各テーブルにデータを投入します。同じコマンドを再度実行しても、cities, prefectures のデータは updateOrCreate() で更新されます。

Usage

あらかじめルートが設定されており、ajax/prefectures/ にアクセスすると都道府県の一覧、ajax/cities/{prefecture}
にアクセスすると市区町村の一覧をJSONデータで取得することができます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

APIのKeyをGithubに上げたくないのでしたこと(PHP)

Google Map APIを利用する際に、自分のAPI keyをGithubに上げたくないので、方法を探していたが、結局以下の方法で動いているのでよしとした。

APIへのアクセス部分は
<script src="https://maps.googleapis.com/maps/api/js?key=<?php include("keys/googlemap.php"); ?>&callback=initMap"></script>

上記アクセス部分が書かれているファイルと同じ階層にディレクトリ「keys」をつくり、その中にファイル名「googlemap.php」でファイルを作成後、そのファイルの中にテキストで自分のAPI keyの値を書くだけ。

そのあと、.gitignoreファイルの中に「keys/」を追加。

以上

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHP使ってユーザ作成・登録する時にパスワードをハッシュ化する

例えば

$lpw = $_POST["lpw"];

とかでログインパスワードをPOSTで受け取った際に

$hash = password_hash($lpw, PASSWORD_DEFAULT);

と記載して、その受け取ったパスワードをハッシュ化して、データベースに書き込むときにそのハッシュ化されたパスワードを放り込む。

$stmt = $pdo->prepare("INSERT INTO test_user_table(id,lid,lpw)VALUES(NULL,:lid,:lpw)");
$stmt->bindValue(':lid', $lid, PDO::PARAM_STR);
$stmt->bindValue(':lpw', $hash, PDO::PARAM_STR);
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初学者向け】LaravelチュートリアルToDoアプリへの機能追加

はじめに

私は所属しているエンジニアサークルでLaravelを学んでいます。
Laravelのとっかかりで、こちらのチュートリアルをやった方も多いんではないでしょうか。
今回はこの完成したToDoアプリに機能追加の第一弾を行おうと思います。

今回やること

今回やりたいことは大きく分けると2つです。

1, ユーザーページを作り下記3つを表示させる
・ユーザー名
・アドレス
・ユーザー名編集ページへのリンク

2, ユーザー名変更機能の実装
・ログイン後であれば任意のユーザー名に変更可能

難易度としてはそこまで高くないですが、WEBサービスを今後作る上で必要な機能なので確実に押さえておきたい所です。

実装までの流れ

コードを書く前に必要な事を整理してきます。

・ ユーザーページへ遷移するためのルーティングを用意
・ ユーザーページへ遷移するためのリンクを用意
・ コントローラーにユーザーの情報を取得するメソッドを用意
・ ユーザーページのテンプレートファイルを用意
・ ユーザーページにユーザー名編集ページへのリンクを用意
・ ユーザー名編集ページへのルーティングを用意
・ ユーザー名編集ページでユーザー名が変更された際のルーティングを用意
・ コントローラーにユーザー名を更新するメソッドを用意

一見すると大変そうですが、1つ1つは大変な作業ではありません。

タスク一覧ページ

まず見た目を確認しておきましょう。
ヘッダー部分にユーザーページというリンクがあるのが分かると思います。
スクリーンショット 2020-02-22 23.37.34.png

ルーティング

では早速web.phpにルーティングを書いていきます。

web.php
Route::get('/users', 'UsersController@showUsers')->name('users.showUsers');

users.showUsersと名前をつけました。

ユーザーページへのリンクを設置

次にヘッダー部分に、ユーザーページへ遷移するためのリンクを準備します。
先ほど定義したルーティングを利用します。

layout.blade.php
        <a href="{{ route('users.showUsers') }}" class="my-navbar-item">ユーザーページ</a>
        |

コントローラー

次に、UsersControllerにメソッドを追加します。

UsersController.php
public function showUsers()  //ユーザー情報を取得
    {
        $user = Auth::user();

        return view('users/showUsers',['user' => $user]);

Auth::を使ってログインしているユーザーの情報を取得し、$userに代入しています。
これでログインしているユーザーの情報は取得できました。
そしてshowUsersというテンプレートに情報を渡しています。
テンプレートファイルはこれから準備します。

ユーザーページ

ユーザーページの見た目を確認をしておきましょう。
冒頭でも説明したように、ユーザー名、アドレス、ユーザー名編集ページへのリンクが表示されているシンプルな画面です。
スクリーンショット 2020-02-22 23.37.43.png

テンプレートファイル

ではユーザーの情報を表示させるshowUsersというテンプレートファイルを準備します。

$ touch resources/views/users/showUsers.blade.php

ファイルが出来上がったら記述します。

showUsers.blade.php
//省略
<p>{{$user->name}}</p>  //ユーザー名
//省略
p>{{$user->email}}</p>  //メールアドレス
//省略
<a href="{{ route('users.editUsers') }}">ユーザー名を編集する</a>  //ユーザー名編集ページへのリンク
//省略

先ほどコントローラーから受け取った$userは認証されたユーザーの情報も保持しています。
$user->でカラムへアクセスすると値を取得し表示できます。

ユーザー名編集ページへのルーティング

ユーザーページに設置したリンクをクリックされた時のルーティングをweb.phpに記述します。

web.php
Route::get('/users/edit', 'UsersController@editUsers')->name('users.editUsers');

users.editUsersと名前をつけました。
ルーティングの名前は自分以外がコードを見た時に、処理の内容をイメージしやすい名前をつけます。

コントローラー

ルーティングで呼ばれたeditUsersメソッドをUsersControllerに記述します。

UsersController.php
public function editUsers()  //ユーザー名編集画面へ遷移する
    {
        return view('users/editUsers');
    }

内容としてはユーザー名編集ページへ遷移するためだけの記述です。
テンプレートファイルであるeditUsersは後から準備します。

ユーザー名編集ページ

最後にユーザー名編集ページの見た目を確認しておきましょう。
スクリーンショット 2020-02-22 23.37.51.png

ルーティング

先に変更ボタンが押された時にメソッドを呼ぶ必要があるため、ルーティングを定義しておきます。

web.php
Route::post('/users/edit','UsersController@updateUsers')->name('users.updateUsers');

今回は入力値があるため、postを使いました。

テンプレートファイル

ユーザー名が入力され変更ボタンが押された時に、先ほど定義したルーティングを利用したいため、フォーム内に記述します。

editUsers.blade.php
//省略
<form action="{{ route('users.updateUsers') }}" method="post">
//省略

コントローラー

UsersController.php
public function updateUsers(Request $request)  //ユーザー名を変更する
    {
        $name = $request->name;

        $edit_user = Auth::user();
        $edit_user->name = $name;
        $edit_user->save(); 

        return redirect()->route('users.editUsers');
    }

こちらが今回の課題の要と言えるでしょうか。
Requestクラスには、アクセスしてきた際の情報が格納されています。
今回の場合、Viewのフォームの中でname = "name"としたため(View省略のため掲載なし)$Requestクラスのオブジェクトでnameにアクセスして、入力された変更したいユーザー名を取得しています。
そして現在ログインしているユーザーの名前に上書きしています。

最後に、ユーザー名を変更しても画面遷移をする必要はないため、ユーザー名編集ページへリダイレクトとしています。

動作確認

では,最後にユーザー名を実際にtestからabcへ変更してみます。
スクリーンショット 2020-02-23 0.57.32.png

変更ボタン押下
スクリーンショット 2020-02-23 0.57.39.png
ヘッダーのユーザー名がabcに変わりましたね。

さいごに

LaravelチュートリアルはLaravel導入にとてもいい教材だと感じました。
また、実際に自身で考えて機能を追加する事で、理解が深まったと強く感じるのでぜひ色々な機能実装に挑戦してみてはいかがでしょうか。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

twitterの情報発信を助けるWebサービス「EMOEMO」を公開して見て感じた事。(個人開発)

はじめに

初めまして!てらって呼んでください:relaxed:
簡単に自己紹介をするとプログラミング初学者です。(3ヶ月目)
現在個人開発中のWEBサービス(EMOEMO)のプロトタイプを先週公開し、今日リニューアルしました。
苦労した点や、実際にどの様に考え何を改善したのかアウトプットしてみようと思います。

↓プロトタイプを試しにデプロイし公開した記事です。
前回の記事

↓Webサービス「EMOEMO」のURLです。
EMOEMOはこちら

結論(問題点=>解決策)

  1. モバイルファーストの欠如 => SPユーザーの離脱率向上
  2. 利用する際UIへの不安感 => 投稿時のUIを整備する
  3. 利用用途の不明瞭性 => アプリケーションの説明を簡略化

上記3点を改善しました。この3つについて今回は書いていきます。

モバイルファーストの欠如 => スマートフォン(SP)ユーザーの離脱率向上

PCのみでの利用を想定していて、スマートフォン(SP)での利用を考えていませんでした。
実際に公開して誰一人登録してくれなかったので、Twitterを利用しているユーザーはスマホでの利用が多い現実を知り、レスポンシブ対応してみる事にしました。

!編集前!
スクリーンショット 2020-02-11 17.37.25.png

!編集後!
スクリーンショット 2020-02-21 12.45.19.png

利用する際UIへの不安感 => 投稿時のUIを整備する

UIがぐちゃぐちゃだったので整えました。CSSがバグって一回大変なことにもなりました。汗。
だいぶマシになった気がします。

!編集前!
スクリーンショット 2020-02-11 17.16.36.png
スクリーンショット 2020-02-11 17.55.22.png
!編集後!
スクリーンショット 2020-02-20 17.10.01.png
スクリーンショット 2020-02-23 0.24.05.png
スクリーンショット 2020-02-21 12.45.39.png

利用用途の不明瞭性 => アプリケーションの説明を簡略化

LP部分の説明が見辛かったので、モダンなサイト真似て見やすい構成にしました。(SPレスポンシブもしています。)

!編集前!
スクリーンショット 2020-02-11 17.37.29.png

!編集後!
スクリーンショット 2020-02-21 12.45.19.png

スクリーンショット 2020-02-21 12.45.16.png

苦労した点

1位
twitterの認証を利用した画像送信関連の実装。
まず、1枚遅れる様にし、それを4枚にする。
その後編集できる様にするのが大変でした。一番時間かかったと思います。

2位
twitter認証でログインする。
コールバックIDの指定がかなり難しく訳わかんないURLの指定をしていてなかなかうまくいきませんでした。
なんとかログインできる様になった瞬間滅茶苦茶嬉しかったのを覚えています。

WEBアプリを個人開発してみて感じた事

色々試しては見たのですが使ってもらうって滅茶苦茶難しいということを身を持って実感しました。WEBアプリケーションを作るのがまず難しいのに実際にそれを使ってもらうのはまじで激ムズです。

↓勉強した事等を呟いています。
twitterアカウント

↓EMOEMOのリンク
EMOEMO

もし最後まで読んでくれている方がいたら嬉しい限りです。
もし気に入ったらいいねをしていただけると嬉しいです!
ありがとうございました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

twitterの情報発信を助けるWebサービス「EMOEMO」を公開してみて感じた事。(個人開発)

はじめに

初めまして!てらです:relaxed:
簡単に自己紹介をするとプログラミング初学者です。(3ヶ月目)
現在個人開発中のWEBサービス(EMOEMO)のプロトタイプを先週公開し、今日リニューアルしました。
苦労した点や、実際にどの様に考え何を改善したのかアウトプットしてみようと思います。

↓プロトタイプを試しにデプロイし公開した記事です。
前回の記事

↓Webサービス「EMOEMO」のURLです。
EMOEMOはこちら

結論(問題点=>解決策)

  1. モバイルファーストの欠如 => SPユーザーの離脱率向上
  2. 利用する際UIへの不安感 => 投稿時のUIを整備する
  3. 利用用途の不明瞭性 => アプリケーションの説明を簡略化

上記3点を改善しました。この3つについて今回は書いていきます。

モバイルファーストの欠如 => スマートフォン(SP)ユーザーの離脱率向上

PCのみでの利用を想定していて、スマートフォン(SP)での利用を考えていませんでした。
実際に公開して誰一人登録してくれなかったので、Twitterを利用しているユーザーはスマホでの利用が多い現実を知り、レスポンシブ対応してみる事にしました。

!編集前!
スクリーンショット 2020-02-11 17.37.25.png

!編集後!
スクリーンショット 2020-02-21 12.45.19.png

利用する際UIへの不安感 => 投稿時のUIを整備する

UIがぐちゃぐちゃだったので整えました。CSSがバグって一回大変なことにもなりました。汗。
だいぶマシになった気がします。

!編集前!
スクリーンショット 2020-02-11 17.16.36.png
スクリーンショット 2020-02-11 17.55.22.png
!編集後!
スクリーンショット 2020-02-20 17.10.01.png
スクリーンショット 2020-02-23 0.24.05.png
スクリーンショット 2020-02-21 12.45.39.png

利用用途の不明瞭性 => アプリケーションの説明を簡略化

LP部分の説明が見辛かったので、モダンなサイト真似て見やすい構成にしました。(SPレスポンシブもしています。)

!編集前!
スクリーンショット 2020-02-11 17.37.29.png

!編集後!
スクリーンショット 2020-02-21 12.45.19.png

スクリーンショット 2020-02-21 12.45.16.png

技術的に苦労した点

1位
twitterの認証を利用した画像送信関連の実装。
まず、1枚遅れる様にし、それを4枚にする。
その後編集できる様にするのが大変でした。一番時間かかったと思います。

2位
twitter認証でログインする。
コールバックIDの指定がかなり難しく訳わかんないURLの指定をしていてなかなかうまくいきませんでした。
なんとかログインできる様になった瞬間滅茶苦茶嬉しかったのを覚えています。

使用した技術

フレームワーク: laravel
データベース: mysql
API:     twitterAPI
デプロイ:   heroku

WEBアプリを個人開発してみて感じた事

色々試しては見たのですが使ってもらうって滅茶苦茶難しいということを身を持って実感しました。WEBアプリケーションを作るのがまず難しいのに実際にそれを使ってもらうのはまじで激ムズです。

↓勉強した事等を呟いています。
twitterアカウント

↓EMOEMOのリンク
EMOEMO

もし最後まで読んでくれている方がいたら嬉しい限りです。
もし気に入ったらいいねをしていただけると嬉しいです!
ありがとうございました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHP書いてて本当に要らないなって思うコメント達

俺の場合、ソースコードから語りかけにくるよね。 By ローランド泉

はじめに

PHPに限った話ではないですが、コメントってそうそういらないと思うんです。
コメントがいるのはあくまで「コードでは伝わりきらない部分を伝えるため」だと思うんです。

なので、全くいらないわけじゃないし、こういう話をすると永遠に答え出ないと思うんです。
でも、なんでこんなコメント頑張って付けてるのかなって思う事が多々あるので、それを個人的にまとめてみました。

※今回はPHPだけに絞って考えてみました。
※今まで自分も漠然と付けてきた部分もあるので、自分への戒めのための記事でもあ---るのです。なんて日だ!!

PHPの標準コーディング規約

色々ありますが、「PSR」などを読んでおけばよいかと。
⇒フレームワークが何を採用しているかは重要なので、あなたが使用しているフレームワークが何基準なのかは押さえておきましょう。

コメントいらない思想

冒頭でも言いましたが、僕はコメントいらない思想です。
っていうのも、僕の師匠がコメントいらない思想だったのは大きいですが。

厳密にはコメントは必要なんですが、コメントいる思想を持ってしまうとコメントに頼ってしまって綺麗にコードを書こうと意識しません。
実際に動くのはソースコードなので、これでは元も子もありません。

ってことで、コメントいらない思想を持った僕の観点でグダグダ書いていきます。

PHPのコメントいらないパターン

まずはサンプルを

sample.php
    /**
     * hogeを取得する
     *
     * @param array $hoge
     * @return string
     */
    public function fetchHoge($hoge)
    {
        $hoge2 = null;

        // $hogeを使った何かしらの処理

        return $hoge2
    }

渡されてきた「hoge」を使って何かしら処理をした後、「hoge2」を返すという意味不明な関数です。
まあ、細かい所は無視してください。
以降、このサンプルで説明します。

いらないパターンその1:コメントに記載されている「型」

sample.php
    /**
     * hogeを取得する
     *
     * @param array $hoge ←ここの「array」
     * @return string      ←ここの「string」
     */

いやーーーーーーーー、いらない。
超いらない。
どれくらいいらないかと言うと、女性に年齢聞いて「何歳だと思います?」って質問で質問を返されるくらいいらない。

sample.php
    /**
     * hogeを取得する
     *
     * @param $hoge ←「array」いらん
     * @return      ←「string」いらん
     */
    public function fetchHoge(array $hoge): string // ←You, ここに型書いちゃいなよ
    {
        $hoge2 = null;

        // $hogeを使った何かしらの処理

        return $hoge2
    }

あんなコメントを書くくらいならこうでしょう。
タイプヒンティングってやつですが、これはPHPのバージョンが7.0以上じゃないと使えないやつとかもあります。

ここで言いたいのは、コメントに書くくらいならコードで保証しましょう。
コメントなんて動作しているものではないので完全に信用なんてできません。

僕ならどこぞの誰が書いたかも分からないクソエンジニア素晴らしいエンジニアのソースコードなんて信じません。

いらないパターンその2:コメントに記載されている「変数名」

sample.php
    /**
     * hogeを取得する
     *
     * @param array $hoge ←ここの「$hoge」
     * @return string
     */

いやーーーーーーーー、いらない。
これはなんですか?
変数名が変わったらコメントも変えるんですか?

凄くイケてない。
どれくらいイケてないかと言うと、おしゃれなスーツ着てるのにスマホ見ながらクチャクチャ食事してる見た目だけ意識高そうなサラリーマン位イケてない。

sample.php
    /**
     * hogeを取得する
     *
     * @param array   ←「$hoge」いらん
     * @return string
     */
    public function fetchHoge($hoge)
    {
        $hoge2 = null;

        // $hogeを使った何かしらの処理

        return $hoge2
    }

変数名なんてコード見たら分かります。
見て分かることをコメントに書くことほど無駄なことはありません。

パターン1,2をまとめると...

sample.php
    /**
     * hogeを取得する
     *
     * @param
     * @return
     */
    public function fetchHoge(array $hoge): string
    {
        $hoge2 = null;

        // $hogeを使った何かしらの処理

        return $hoge2
    }

こうなると、もはや「param」と「return」の記載自体いらなくなりますが、もし仮にこれを消すと、そもそも「もうコメントいらなくね?」ってなります。
勿論それでもよいのですが、現場では「param」と「return」を書くケースはそれなりに多い気がします。
⇒あくまで僕の感覚。

なので、「param」と「return」を残しつつ、いい感じにしていくのがベストとします(勝手に)。

いい感じにコメントを書くとこんな感じかな?

sample.php
    /**
     * hogeを取得する
     *
     * @param  ほげ~(本来は、変数の説明を日本語で分かりやすく記載する)
     * @return ほげ~2(本来は、変数の説明を日本語で分かりやすく記載する)
     */
    public function fetchHoge(array $hoge): string
    {
        $hoge2 = null;

        // $hogeを使った何かしらの処理

        return $hoge2
    }

コメントを書くと決めた以上、最小限に、かつ日本語で説明を書いてあげるのがベストな気がします。
これであれば、あくまで説明なので2重メンテ(変数名を変えたらコメントの方も変えるみたいなこと)にもなりません。
まあ、変数の役割などが変わってくるとあれですが、そこは

  • paramとかのコメントも書かない
  • 仕方ないとして今回のようなコメントの書き方にする

かを決めるべきでしょうね。

おまけ

厳格な型付けは必要か?

タイプヒンティングは、厳密には「弱い型付け」と呼ばれる状態です。
例えば、引数に「int $hoge」と宣言されているものがあるとして、ここに「"123"」という文字列を渡すと、PHPは限界まで頑張って暗黙の型変換を行います。
これを良しとしない方法として、以下を記載することがあります。

declare(strict_types=1);

ただ、個人的にはそこまでしなくてもいいんじゃないかと思います。
いや、実はやりたいんですが、毎回これを書くのがダサい。すごくダサい。

そう、もはやこれは好みの問題なのです。
いや、もはやこれは愛の問題なのです。

これもすごくダサくない?

    /**
     * hogeを取得する
     *
     * @return void
     */

これはさっきの話で「void」をタイプヒンディングでつければいいんですが、そこではなくて、「そもそも返すものないのにreturnいらんやろ」って話です。
要はコメントが過剰に頑張っちゃってるって話です。
どれくらい過剰かって言うと、インフルエンザ流行ってる時期に冷えピタおでこに貼りながら出勤してくるお馬鹿さんくらい過剰に頑張っています。

PHPにタイプヒンティングってどうなのよ?っていう声

PHPは型がない言語として認識されています。
メリットでよく言われるのは「自由度が高い」こと。

型なし言語をゴリゴリ使っている人からすると、タイプヒンティングは自由度を殺すように思えるかもしれません。
僕も最初はそう思っていましたが、そもそも「型なし」だという事自体が間違っています。
型はないのではなく、型が暗黙的に解釈されているのであって、型はあるのです。

つまり、

  • 型はあるけど型はない
  • 型はないけど型はある

のです。

そうなると、元々あった型を明示的に書いてあげてるわけですから、「何ら問題はないよね?」ってことになります。
どれくらい問題がないかって言うと、旅行に行ってわざわざお土産を買ってこなくても問題ないよね?ってくらい問題がない。

PHPDocumentorとかいらんやろ

param」とかのコメントってちゃんと書いておくと、PHPDocumentorってやつで自動的にドキュメントを吐き出せるようです。
つまり、ここらへんちゃんと書いておかないとPHPDocumentorでは自動生成できないと思われます(使ったことないから知らん)。

じゃあここで疑問が出てくるわけです。
そもそもソースコードのドキュメントなんていりますか?
いや、いらない。

僕は元々Java屋さんですが、JavaDoc(でしたっけ?)なんて見たことない。
そんなん見るなら直接コード見るわ。

それに、ソースコードの設計書の前にちゃんとした設計書あるでしょ?
いらないいらない。

いらないものに対して頑張ってコメントをきれいに書いても、いらないものはいらない。
いらないものはどこまで行ってもいらないです。

あくまで個人的な見解です。←ここ重要。テストに出ます。

おわりに

最後に素晴らしい俳句で締めたいと思います。

コメントは、必要そうで、必要ない By ローランド泉

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む