20210111のPHPに関する記事は10件です。

VSCode + Docker + PHP の開発環境を、XDebugでデバッグする。

はじめに

扱っていたプロジェクトは Laravel を使ったPHPアプリケーションで、VSCodeによって製作されていました。
Java や Swift を使った作業には慣れていたのですが、PHPのデバッグが久しぶりで大いにはまったので備忘録です。

やったこと

PHPのデバッグには XDebug を使うということなので、XDebug解説記事 をふむふむと読み(大変わかりやすい記事です)作業に当たりました。

たくさんの記事が丁寧に説明しているので詳細は端折りますが

php.ini
;...省略

[XDebug]
zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20190902/xdebug.so
xdebug.default_enable=1
xdebug.remote_port=9000
xdebug.remote_autostart=1
xdebug.remote_handler=dbgp
xdebug.remote_connect_back=0
xdebug.remote_host=host.docker.internal
xdebug.remote_log=/tmp/xdebug.log
xdebug.idekey=VSCODE
Dockerfile
FROM php:7.4-apache

# XDebug
RUN pecl install xdebug \
  && docker-php-ext-enable xdebug

#...省略
launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Listen for XDebug",
      "type": "php",
      "request": "launch",
      "port": 9000,
      "log": true,
      "pathMappings": {
        "/var/www/html": "${workspaceFolder}/src"
      },
      "ignore": [
          "**/vendor/**/*.php"
      ]
    }
  ]
}

こんな感じで、PHP初期化、Docker初期化、XCodeのデバッグ設定を終えました。

これが全然びくとも動かない。

解決策

いろんなパラメータをいじり倒しましたが全然動かず諦めかけましたが、最終的には xdebug のバージョンの問題ということに気づきました。

$ php -v | grep -i "xdebug"
    with Xdebug v3.0.2, Copyright (c) 2002-2021, by Derick Rethans

Xdebug 2.x から 3.x で、設定値が様変わりしています。
https://xdebug.org/docs/upgrade_guide
このドキュメントに詳しくわかりやすく書いてあります。

たとえば、xdebug.remote_logxdebug.log に Rename されています。どうりで、ログもさっぱり出ないわけです。

細かい意味はそちらを見ていただくとして、上記の php.ini は正しくはこうなりました。

php.ini
;...省略

[XDebug]
zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20190902/xdebug.so
xdebug.mode=debug
xdebug.client_port=9000
xdebug.start_with_request=yes
xdebug.discover_client_host=0
xdebug.client_host=host.docker.internal
xdebug.log=/tmp/xdebug.log

現場からは以上です。

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

Dockerでphpの設定

Dockerfile

Dockerfile.
FROM php:x.x-fpm

COPY ./php.ini /usr/local/etc/php/php.ini
COPY ./php-fpm.d/www.conf /usr/local/etc/php-fpm.d/zzz-www.conf

まずphp.inizzz-www.confをコピーする。

php.iniの内容

の中でも意味のわかるものを載せます。(文字コードを省く)

php.ini
;エラー時にブラウザにエラー内容を表示(開発環境でならon)
desplay_errors = On 
;エラーログを吐く設定を有効に
log_errors = On
;phpのエラーログを /var/log/php_error.log に吐く設定
error_log = /var/log/php_error.log

;値は自由に
;メモリーの上限を256MBに
memory_limit = 256M
;POSTリクエストの受付る最大値
post_max_size = 128M
;アップロードファイルの受付上限
upload_max_filesize = 64M

;レスポンスヘッダにPHPのバージョンを記載しない
expose_php = Off
;セッションIDのハッシュアルゴリズムをSHA-1(160bit)に変更
session.hash_function = 1
;強制終了までの許容時間
max_execution_time = 30
;入力変数の最大許容数
max_input_vars = 1000

; PHPファイルのタグを<?php ?>のみ利用可能と制限(<? ?>などを使用不可にする)
short_open_tag = Off
;Time zone
date.timezone = 設定したいTZ

私はこの記事を参考にしました。参考記事
大体2,3個の記事を参考にしたら自力で書けそう。

zzz-www.confの内容

ファイル名がこれなのは公式イメージのzz-docker.confでlistenを上書きしてしまわないようにzz-docker.confの後に読ませたいので、後に読ませられればなんでもいい。

zzz-www.conf
listen = /var/run/php-fpm/php-fpm.sock
listen.group = www-data
listen.owner = www-data
listen.mode = 0666

1行目はソケットの位置を指定。(nginxの設定と合わせる)
4行目listen.modeはデフォルトのlisten.mode = 0660だとパーミッションエラーが起きるようで0666にした方がいい。
4行目の参考Nginx+PHP-FPMでUNIXドメインソケットを使っていてハマる

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

PHP PDOクラスでデータを取得する方法

環境

・PHP7
・MAMP
・phpMyAdmin

①データの取得

function connect_db(){
    //ホスト名、データベース名、文字コードの3つを定義する
    $host = 'localhost';
    $db = 'lesson';
    $charset = 'utf8';
    $dsn = "mysql:host=$host; dbname=$db; charset=$charset";

    //ユーザー名、パスワード
    $user = 'root';
    $pass = 'root';

    //オプション
    $options = [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES   => false,
    ];

    try{

        //上のデータを引数に入れて、PDOインスタンスを作成
        $pdo = new PDO($dsn, $user, $pass, $options);

    }catch(PDOException $e){
        echo $e->getMessage();
    }

    //PDOインスタンスを返す
    return $pdo;
}

//データベースと接続して、PDOインスタンスを取得
$pdo = connect_db();

//実行したいSQLを準備する
$sql = 'select * from lesson_pdo';
$stmt = $pdo->prepare($sql);

//SQLを実行
$stmt->execute();

//データベースの値を取得
$result = $stmt->fetchall();

②データの表示

データベースから取得されたデータは、連想配列になっている

foreach($result as $r){
    foreach($r as $key => $value){
        echo $key . ' * '. $value;
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【ギリ初心者向け】Laravel Docker AWS(EC2) Webアプリ(PHP)を0から簡単にデプロイする方法(無料)② ーDocker開発環境構築編(Laravel)ー

0.概要 

何度もいいますが、知らない単語が出た瞬間ググってください!!!!!
①の全体像編がこちらにあるのでこちらを一読してからだと理解がスムーズかと!!!
https://qiita.com/SG_Sg/items/6b8ce48567b6b6602805 
今回で作成するは具体的にいうと赤いとこ
qiita-square

Dokcerを利用してLaravel(PHP)のプロジェクトを作成(dockerの説明)

さて具体的にDockerをを利用して環境構築したいが、、、、
「Dockerってなんやねん」「Docker使うメリットなんやねん」「開発現場でどうやって使うねん」
疑問だらけのため、ざっっくり説明してからにしよう!(最初いくらググってもマジでちょっと何言ってるかわかんないっすねって感じでした)
Dockerとは??等細かいところはググってくださいな、、

1.Dockerのメリット、なぜプロのエンジニアは使うのか

①MACを汚さずに環境とプロジェクト、プログラムを作れる!
どういうことかって???
Dockerを使わずにプロジェクトをつくるとどうなるかみてみよう!!
qiita-square
こんな風にバージョン違いだったり他のPCの環境に依存してしまう!!

Dockerを使うプロジェクトをつくるとどうなるかみてみよう!!
qiita-square

Dockerを使えばDockerの中に環境をインストールしてプロジェクトごとgithub上にのっけるイメージ
Docker内に必要な環境をインストールするから
Macに必要な環境をインストールしなくて良い!!

2.まずはいろいろ準備(GitとかDockerをインストールとか)

以下デフォルトのターミナル使ってるよ!
①githubアカウントの作成
https://github.com
②Gitの初期設定
すみません。。「Mac git初期設定」でググってください汗
最終的に下記のように表示されればokです。

MacBook-Pro% git config --list | grep user
user.name=[githubname]
user.email=67626524+[githubname]@users.noreply.github.com

③GithubSSH接続設定
これも「Mac Github SSH接続」とかでググってね!エラーとかがでたらまたそのエラー文をぐぐるんや!!!

MacBook-Pro% ssh -T github.com
Hi [githubの名前]! You've successfully authenticated, but GitHub does not provide shell access.

こんなかんじにsuccessfullyの文字が出れば大体いける!

④ docker, docker-compose(起動したり停止できたりするやつ)のインストール
Docker for Macをインストール
https://docs.docker.com/docker-for-mac/install
インストール確認(なにかインストールしたら必ずインストールされてるか確認!)

MacBook-Pro% docker --version
Docker version 20.10.0, build 7287ab3
MacBook-Pro% docker-compose --version
docker-compose version 1.27.4, build 40524192

Docker起動確認
スクリーンショット 2021-01-10 15.42.16.png
これで準備完了なはず!!

3.Dockerプロジェクトを作る!!

3-1.github動作確認まで

①プロジェクト(ディレクトリ)を作成する
私はホームディレクトリに「LaravelProjext」をつくってその中に「docker-test」ディレクトリを作成!!このへんはご自由に!!!

MacBook-Pro % mkdir LaravelProject
MacBook-Pro % cd LaravelProject
MacBook-Pro LaravelProject % mkdir docker-test
MacBook-Pro LaravelProject % cd docker-test 
MacBook-Pro docker-test % 

②リモートリポジトリを作る
作り方は「giuhubリモートリポジトリ 作成」でググろう!!
「DockerLaravelTestProject」を作成
スクリーンショット 2021-01-10 16.04.20.png

②リモートリポジトリにテストプッシュ!Gitが機能しているかの確認

//README.mdファイルを作成
MacBook-Pro docker-test % echo "README import First" >> README.md
//git管理できるようにする
MacBook-Pro docker-test % git init
//ステージングにaddする!
MacBook-Pro docker-test % git add . 
//commitする!!
MacBook-Pro docker-test % git commit -m "first commit README"
//push先のリモートリポジトリをGithubに!!(SSHで接続 ※URLはSSH)
MacBook-Pro docker-test % git remote add origin git@github.com:SugiKoki/DockerLaravelTestProject.git
//リモートリポジトリ先を確認!しっかりgithubのプロジェクトになっている
MacBook-Pro docker-test % git remote -v
origin  git@github.com:SugiKoki/DockerLaravelTestProject.git (fetch)
origin  git@github.com:SugiKoki/DockerLaravelTestProject.git (push)
//gitのブランチを確認
MacBook-Pro docker-test % git branch
* master
//gitのブランチ(master)にプッシュ
MacBook-Pro docker-test % git push -u origin master
kokisugi@sugihirokinoMacBook-Pro docker-test % 

③VScodeで確認する
スクリーンショット 2021-01-10 16.58.18.png
しっかりディレクトリの中に書かれていることを確認!!これで作業できる!!!!

3-2.最終ゴールの確認

ファイル構成はこんな感じをめざすよ!!
スクリーンショット 2021-01-10 17.06.23.png
backendの中が実際にプログラミングするところ!!

3-3.アプリケーションサーバー(app)を作る(入れる)

①docker-compose.yml を作成する

MacBook-Pro docker-test % touch docker-compose.yml

VScodeでディレクトリを開いて以下のようにする
qiita-square
以下が内容

version: "3.8"
services:
  app:
    build: ./infra/php
    volumes:
      - ./backend:/work
  web:
    image: nginx:1.18-alpine
    ports:
      - 10080:80
    volumes:
      - ./backend:/work
      - ./infra/nginx/default.conf:/etc/nginx/conf.d/default.conf
    working_dir: /work
  db:
    build: ./infra/mysql
    volumes:
      - db-store:/var/lib/mysql
volumes:
  db-store:

上のappってとこがアプリケーションサーバー
真ん中のwebってとこがwebサーバー
下のdbがデータベースサーバー

作りたい環境をここで設定してこれに合わせてDockerにインストールしていく!!!

②./docker/php/Dockerfile を作成する

MacBook-Pro docker-test % mkdir -p infra/php
MacBook-Pro docker-test % touch infra/php/Dockerfile

下記のコードを Dockerfile へ。
スクリーンショット 2021-01-10 17.28.12.png

FROM php:7.4-fpm-buster
SHELL ["/bin/bash", "-oeux", "pipefail", "-c"]

ENV COMPOSER_ALLOW_SUPERUSER=1 \
  COMPOSER_HOME=/composer

COPY --from=composer:1.10 /usr/bin/composer /usr/bin/composer

RUN apt-get update && \
  apt-get -y install git unzip libzip-dev libicu-dev libonig-dev && \
  apt-get clean && \
  rm -rf /var/lib/apt/lists/* && \
  docker-php-ext-install intl pdo_mysql zip bcmath

COPY ./php.ini /usr/local/etc/php/php.ini

WORKDIR /work

ここで行っていること
Composerコマンドのインストール
Laravelで必要な
bcmath, pdo_mysql が不足しているのでインストール

③./docker/php/Dockerfile を作成する

MacBook-Pro docker-test % touch infra/php/php.ini

スクリーンショット 2021-01-10 17.35.52.png

以下のコードをphp.iniへ

zend.exception_ignore_args = off
expose_php = on
max_execution_time = 30
max_input_vars = 1000
upload_max_filesize = 64M
post_max_size = 128M
memory_limit = 256M
error_reporting = E_ALL
display_errors = on
display_startup_errors = on
log_errors = on
error_log = /dev/stderr
default_charset = UTF-8

[Date]
date.timezone = Asia/Tokyo

[mysqlnd]
mysqlnd.collect_memory_statistics = on

[Assertion]
zend.assertions = 1

[mbstring]
mbstring.language = Japanese

3-4.ウェブサーバー(web)を作る(入れる)

①docker/nginx/default.conf を作成する

MacBook-Pro docker-test % mkdir infra/nginx
MacBook-Pro docker-test % touch infra/nginx/default.conf

スクリーンショット 2021-01-10 17.44.41.png
以下のコードを貼り付ける!!

server {
    listen 80;
    server_name example.com;
    root /work/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_pass app:9000;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

3-5.データベース(db)サーバーを作る(入れる)

①./docker/mysql/Dockerfile を作成する

MacBook-Pro docker-test % mkdir infra/mysql
MacBook-Pro docker-test % touch infra/mysql/Dockerfile

スクリーンショット 2021-01-10 17.58.18.png

以下のコードを貼り付ける!

FROM mysql:8.0

ENV MYSQL_DATABASE=sg_db \
  MYSQL_USER=sg \
  MYSQL_PASSWORD=sg \
  MYSQL_ROOT_PASSWORD=sg \
  TZ=Asia/Tokyo

COPY ./my.cnf /etc/mysql/conf.d/my.cnf
RUN chmod 644 /etc/mysql/conf.d/my.cnf

ここは任意なので好きにしてもらって結構!
データベースを接続するときの名前とパスワードだから
忘れないようにおぼえておこう!

  MYSQL_USER=sg \
  MYSQL_PASSWORD=sg \
  MYSQL_ROOT_PASSWORD=sg \

②docker/mysql/my.cnf を作成する

MacBook-Pro docker-test % touch infra/mysql/my.cnf

スクリーンショット 2021-01-10 17.59.49.png

以下のコードを貼り付ける

[mysqld]
# character set / collation
character_set_server = utf8mb4
collation_server = utf8mb4_0900_ai_ci

# timezone
default-time-zone = SYSTEM
log_timestamps = SYSTEM

# Error Log
log-error = mysql-error.log

# Slow Query Log
slow_query_log = 1
slow_query_log_file = mysql-slow.log
long_query_time = 1.0
log_queries_not_using_indexes = 0

# General Log
general_log = 1
general_log_file = mysql-general.log

[mysql]
default-character-set = utf8mb4

[client]
default-character-set = utf8mb4

これで3つのコンテナが完成!!!!しっかり最終的なディレクトリ構成になりましたか???

3-6.Docker起動!(中身の確認)

①dockerを動かしたいときに使うよ!

MacBook-Pro docker-test % docker-compose up -d --build
・・・・
Successfully built 9813d5181de8
Successfully tagged docker-test_db:latest
Creating docker-test_app_1 ... done
Creating docker-test_db_1  ... done
Creating docker-test_web_1 ... done
MacBook-Pro docker-test % 

上の感じにdoneとでたらそれらはOKということ!
・動かした状態でどう動いてるのか確認!

MacBook-Pro docker-test % docker-compose ps
      Name                     Command               State           Ports        
----------------------------------------------------------------------------------
docker-test_app_1   docker-php-entrypoint php-fpm    Up      9000/tcp             
docker-test_db_1    docker-entrypoint.sh mysqld      Up      3306/tcp, 33060/tcp  
docker-test_web_1   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:10080->80/tcp

ちなみにリスタートしたりしたかったら、一度止めたかったらdown!

MacBook-Pro docker-test % docker-compose down
//一度止めたらまた起動しよう
MacBook-Pro docker-test % docker-compose up -d --build

Dockerに入れたそれぞれサーバー(コンテナ)内に入れたのバージョン確認する方法

・appサーバー

MacBook-Pro docker-test %  docker-compose exec app bash
//PHPのバージョン確認
root@5ce9c9fa1435:/work# php -V
//composerのバージョン確認
root@5ce9c9fa1435:/work# composer -v
//インストール済みの拡張機能一覧の確認
root@5ce9c9fa1435:/work# php -m
//dockerから出る
root@5ce9c9fa1435:/work# exit 

・webサーバー

MacBook-Pro docker-test % docker-compose exec web nginx -v

・DBサーバー

MacBook-Pro docker-test % docker-compose exec db bash
//mysqlのバージョン確認
root@6bcf6de7e31e:/# mysql -V
//dockerから出る
root@6bcf6de7e31e:/work# exit 

これでDocker環境構築終了だ!!!さあLaravelを入れてプログラミングしていきます!!!

定期的にGitコミットはしていったほうがよいですよ!

MacBook-Pro docker-test % git add .
MacBook-Pro docker-test % git commit -m  "laravel commit"
MacBook-Pro docker-test % git push

3-7.Laravelをインストールする(appサーバー上でやります)

①appに入って、Laravelをインストール

MacBook-Pro docker-test % docker-compose exec app bash
root@5ce9c9fa1435:/work# composer create-project --prefer-dist "laravel/laravel=8.*" .
//laravelバージョン確認
root@5ce9c9fa1435:/work# php artisan -V
Laravel Framework 8.21.0
root@5ce9c9fa1435:/work# exit 

②Laravel ウェルカム画面の表示
http://127.0.0.1:10080
にアクセス!!!
スクリーンショット 2021-01-10 18.41.21.png
・VScode確認するとbackendこんな感じになっているはず!
スクリーンショット 2021-01-10 18.44.21.png

3-8.プログラミングしてみる!!(html,blade.phpファイルを作って表示できるか確認!)

HTML(.blade.php)を表示してみよう!!MVCモデルで進めていきます!

①backend/resources/viewsのなかに
helloディレクトリを作成
helloディレクトリの中にhello.blade.phpを作成

スクリーンショット 2021-01-10 18.53.45.png
中身はこれとする。貼り付けてOKです!

<html>
    <body>
        <h1>HELLO Larabel<h1>
    </body>
</html>

②URLから呼び出すコントローラーを設定!
・backend/routes/web.phpを修正
スクリーンショット 2021-01-10 21.01.54.png
以下のコードをbackend/routes/web.phpに追加する!

/// URL/helloのとき「HelloController」を呼び出す
Route::get('hello', 'App\Http\Controllers\HelloController@index');

③backend/app/http/Controllers/の中に
HelloController.phpを作成する

スクリーンショット 2021-01-10 21.06.24.png
以下のコードをbackend/app/http/Controllers/の中に
HelloController.phpに追加する!

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\KrononUser;
use Faker\Provider\ar_JO\Person;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class HelloController extends Controller
{
    public function index()
    {
        return view('hello.hello');
    }
}

④URLにアクセスして表示!!!
http://127.0.0.1:10080/hello
スクリーンショット 2021-01-10 21.45.34.png

3-9.データベースに接続してみる!!!!

ソースコード上で backend/.env のDB接続設定を修正する。
スクリーンショット 2021-01-10 21.54.15.png
①以下のコードに変更!!DBサーバー作った時のに合わせながら!

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=sg_db
DB_USERNAME=sg
DB_PASSWORD=sg

スクリーンショット 2021-01-10 21.57.32.png
②backend/.env.example も同様に変更する

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=sg_db
DB_USERNAME=sg
DB_PASSWORD=sg

ちなみにgitcloneした際はここからやれば動きます

③Laravelインストール

app コンテナにはいってからいろいろ

MacBook-Pro docker-test % docker-compose exec app bash
//コンポーザーをインストールする
root@36ffabe3ffc9:/work# composer install
//.env.exampleを.envファイルにコピーする
root@36ffabe3ffc9:/work# cp .env.example .env
//このコマンドでアプリケーションキーを生成できます。
root@36ffabe3ffc9:/work# php artisan key:generate
Application key set successfully.

//デフォルトで入っているマイグレーションを実行!!デフォルトのテーブルがDBに反映される
root@36ffabe3ffc9:/work# php artisan migrate
Migration table created successfully.
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (40.88ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (37.06ms)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (35.00ms)

これでデフォルトですが、DBにテーブルなどが入りました!!

④データベースの確認(デフォルト)

MacBook-Pro docker-test % docker-compose exec db bash 
//設定したUSERでmysqlにログイン
root@d94d20dd2212:/# mysql -u sg -p
//設定したPASSWORDを入力.envに書いた!!
Enter password: 
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| sg_db              |
+--------------------+
2 rows in set (0.01 sec)
mysql> use sg_db
Database changed
mysql> show tables;
+-----------------+
| Tables_in_sg_db |
+-----------------+
| failed_jobs     |
| migrations      |
| password_resets |
| users           |
+-----------------+

⑤migrationをつくってアプリに反映する!!
スクリーンショット 2021-01-11 13.51.27.png
/backend/database/migration/2021_01_03_090902_create_people_table.php
を作成

※/backend/database/migration/の中にデフォルトでいろいろ入っているからそれをコピーすればいいかも!!
以下のコードを貼り付け!

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePeopleTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('people', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('mail');
            $table->integer('age');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('people');
    }
}

⑥migrationを実行(appコンテナ)の中に入って実行!
appのなかじゃないとdockerにあるDBコンテナに届かない

MacBook-Pro docker-test % docker-compose exec app bash
root@36ffabe3ffc9:/work# php artisan migrate
Migrating: 2021_01_03_090902_create_people_table
Migrated:  2021_01_03_090902_create_people_table (49.03ms)

⑦Seederを作成する!!まずはデフォルトにあるDatabaseSeeder.phpから
"Seederとは??"
ダミーデータ。データベースにコマンドを実行するだけでデータを入れられる!!
スクリーンショット 2021-01-11 14.37.11.png
DatabaseSeeder.phpに以下のソースを貼り付け

$this->call(PeopleTableSeeder::class);

呼び出される側のPeopleTableSeeder.phpを作成
スクリーンショット 2021-01-11 14.40.27.png
PeopleTableSeeder.phpに以下のソースを貼り付け

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class PeopleTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $param = [
            'id' => 1,
            'name' => 'test',
            'mail' => 'test',
            'age' => 20,
        ];
    DB::table('people')->insert($param);
    }

}

⑧Seederを実行する!

MacBook-Pro docker-test % docker-compose exec app bash
root@36ffabe3ffc9:/work# php artisan db:seed
Seeding: Database\Seeders\PeopleTableSeeder
Seeded:  Database\Seeders\PeopleTableSeeder (29.08ms)
Database seeding completed successfully.

これでテーブルはできたし、ダミーデータもできました!あとはweb上で表示すれば完璧ですね!!

データベースに登録されているデータを表示する

①views/hello.blade.phpを作成
スクリーンショット 2021-01-11 14.49.15.png
以下のソースhello.blade.phpを変更

<html>
    <body>
        <h1>HELLO Larabel<h1>
            <h1>DBから表示しているよ<h1>
            <tr><th>Name</th><th>Mail</th><th>Age</th></tr>
                <br>
                @foreach ($items as $item)
                <tr>
                    <td>{{$item -> name}}</td>
                    <td>{{$item -> mail}}</td>
                    <td>{{$item -> age}}</td>
                </tr>
            @endforeach
    </body>
</html>

②Controllers/HelloController.phpを変更
スクリーンショット 2021-01-11 14.50.24.png
以下のソースに変更する

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\KrononUser;
use Faker\Provider\ar_JO\Person;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class HelloController extends Controller
{
    public function index()
    {
        $items = DB::table('people')->get();
        return view('hello.hello',['items' => $items]);
    }
}

③作成したアプリにアクセス!!
http://127.0.0.1:10080/hello
スクリーンショット 2021-01-11 14.53.14.png
これでDBさきほどSeederでいれたダミーデータが表示されていたら完璧ですね!!!
最後にcommmitして終了!!!

MacBook-Pro docker-test % git add .
MacBook-Pro docker-test % git commit -m "db complete"
MacBook-Pro docker-test % git push

あとはこれを世の中に出すためAWSを使えればOK!!!
次回にご期待!!

お疲れ様でした

こういった環境構築かなり疲れますよねーもうへとへとです
全体像を確認したければこちら
【ギリ初心者向け】Laravel Docker AWS(EC2) Webアプリ(PHP)を0から簡単にデプロイする方法(無料)① ー全体像編ー
https://qiita.com/SG_Sg/items/6b8ce48567b6b6602805
次回は③
【ギリ初心者向け】Laravel Docker AWS(EC2) Webアプリ(PHP)を0から簡単にデプロイする方法(無料)③ ーEC2にデプロイ編ー
を予定してます。

参考文献

【超入門】20分でLaravel開発環境を爆速構築するDockerハンズオン
https://qiita.com/ucan-lab/items/56c9dc3cf2e6762672f4
↑の方の記事めちゃくちゃわかりやすいし、細かく書いてあるのでこちらも参考にしていただければ
特に最初の初期設定の情報のまとまりがすばらしいです。この記事の上位互換。

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

【ギリ初心者向け】Laravel Docker AWS(EC2) Webアプリ(PHP)を0から簡単にデプロイする方法(無料)② ーDocker開発環境構築編ー

0.概要 

何度もいいますが、知らない単語が出た瞬間ググってください!!!!!
①の全体像編がこちらにあるのでこちらを一読してからだと理解がスムーズかと!!!
https://qiita.com/SG_Sg/items/6b8ce48567b6b6602805 
今回で作成するは具体的にいうと赤いとこ
qiita-square

Dokcerを利用してLaravel(PHP)のプロジェクトを作成(dockerの説明)

さて具体的にDockerをを利用して環境構築したいが、、、、
「Dockerってなんやねん」「Docker使うメリットなんやねん」「開発現場でどうやって使うねん」
疑問だらけのため、ざっっくり説明してからにしよう!(最初いくらググってもマジでちょっと何言ってるかわかんないっすねって感じでした)
Dockerとは??等細かいところはググってくださいな、、

1.Dockerのメリット、なぜプロのエンジニアは使うのか

①MACを汚さずに環境とプロジェクト、プログラムを作れる!
どういうことかって???
Dockerを使わずにプロジェクトをつくるとどうなるかみてみよう!!
qiita-square
こんな風にバージョン違いだったり他のPCの環境に依存してしまう!!

Dockerを使うプロジェクトをつくるとどうなるかみてみよう!!
qiita-square

Dockerを使えばDockerの中に環境をインストールしてプロジェクトごとgithub上にのっけるイメージ
Docker内に必要な環境をインストールするから
Macに必要な環境をインストールしなくて良い!!

2.まずはいろいろ準備(GitとかDockerをインストールとか)

以下デフォルトのターミナル使ってるよ!
①githubアカウントの作成
https://github.com
②Gitの初期設定
すみません。。「Mac git初期設定」でググってください汗
最終的に下記のように表示されればokです。

MacBook-Pro% git config --list | grep user
user.name=[githubname]
user.email=67626524+[githubname]@users.noreply.github.com

③GithubSSH接続設定
これも「Mac Github SSH接続」とかでググってね!エラーとかがでたらまたそのエラー文をぐぐるんや!!!

MacBook-Pro% ssh -T github.com
Hi [githubの名前]! You've successfully authenticated, but GitHub does not provide shell access.

こんなかんじにsuccessfullyの文字が出れば大体いける!

④ docker, docker-compose(起動したり停止できたりするやつ)のインストール
Docker for Macをインストール
https://docs.docker.com/docker-for-mac/install
インストール確認(なにかインストールしたら必ずインストールされてるか確認!)

MacBook-Pro% docker --version
Docker version 20.10.0, build 7287ab3
MacBook-Pro% docker-compose --version
docker-compose version 1.27.4, build 40524192

Docker起動確認
スクリーンショット 2021-01-10 15.42.16.png
これで準備完了なはず!!

3.Dockerプロジェクトを作る!!

3-1.github動作確認まで

①プロジェクト(ディレクトリ)を作成する
私はホームディレクトリに「LaravelProjext」をつくってその中に「docker-test」ディレクトリを作成!!このへんはご自由に!!!

MacBook-Pro % mkdir LaravelProject
MacBook-Pro % cd LaravelProject
MacBook-Pro LaravelProject % mkdir docker-test
MacBook-Pro LaravelProject % cd docker-test 
MacBook-Pro docker-test % 

②リモートリポジトリを作る
作り方は「giuhubリモートリポジトリ 作成」でググろう!!
「DockerLaravelTestProject」を作成
スクリーンショット 2021-01-10 16.04.20.png

②リモートリポジトリにテストプッシュ!Gitが機能しているかの確認

//README.mdファイルを作成
MacBook-Pro docker-test % echo "README import First" >> README.md
//git管理できるようにする
MacBook-Pro docker-test % git init
//ステージングにaddする!
MacBook-Pro docker-test % git add . 
//commitする!!
MacBook-Pro docker-test % git commit -m "first commit README"
//push先のリモートリポジトリをGithubに!!(SSHで接続 ※URLはSSH)
MacBook-Pro docker-test % git remote add origin git@github.com:SugiKoki/DockerLaravelTestProject.git
//リモートリポジトリ先を確認!しっかりgithubのプロジェクトになっている
MacBook-Pro docker-test % git remote -v
origin  git@github.com:SugiKoki/DockerLaravelTestProject.git (fetch)
origin  git@github.com:SugiKoki/DockerLaravelTestProject.git (push)
//gitのブランチを確認
MacBook-Pro docker-test % git branch
* master
//gitのブランチ(master)にプッシュ
MacBook-Pro docker-test % git push -u origin master
kokisugi@sugihirokinoMacBook-Pro docker-test % 

③VScodeで確認する
スクリーンショット 2021-01-10 16.58.18.png
しっかりディレクトリの中に書かれていることを確認!!これで作業できる!!!!

3-2.最終ゴールの確認

ファイル構成はこんな感じをめざすよ!!
スクリーンショット 2021-01-10 17.06.23.png
backendの中が実際にプログラミングするところ!!

3-3.アプリケーションサーバー(app)を作る(入れる)

①docker-compose.yml を作成する

MacBook-Pro docker-test % touch docker-compose.yml

VScodeでディレクトリを開いて以下のようにする
qiita-square
以下が内容

version: "3.8"
services:
  app:
    build: ./infra/php
    volumes:
      - ./backend:/work
  web:
    image: nginx:1.18-alpine
    ports:
      - 10080:80
    volumes:
      - ./backend:/work
      - ./infra/nginx/default.conf:/etc/nginx/conf.d/default.conf
    working_dir: /work
  db:
    build: ./infra/mysql
    volumes:
      - db-store:/var/lib/mysql
volumes:
  db-store:

上のappってとこがアプリケーションサーバー
真ん中のwebってとこがwebサーバー
下のdbがデータベースサーバー

作りたい環境をここで設定してこれに合わせてDockerにインストールしていく!!!

②./docker/php/Dockerfile を作成する

MacBook-Pro docker-test % mkdir -p infra/php
MacBook-Pro docker-test % touch infra/php/Dockerfile

下記のコードを Dockerfile へ。
スクリーンショット 2021-01-10 17.28.12.png

FROM php:7.4-fpm-buster
SHELL ["/bin/bash", "-oeux", "pipefail", "-c"]

ENV COMPOSER_ALLOW_SUPERUSER=1 \
  COMPOSER_HOME=/composer

COPY --from=composer:1.10 /usr/bin/composer /usr/bin/composer

RUN apt-get update && \
  apt-get -y install git unzip libzip-dev libicu-dev libonig-dev && \
  apt-get clean && \
  rm -rf /var/lib/apt/lists/* && \
  docker-php-ext-install intl pdo_mysql zip bcmath

COPY ./php.ini /usr/local/etc/php/php.ini

WORKDIR /work

ここで行っていること
Composerコマンドのインストール
Laravelで必要な
bcmath, pdo_mysql が不足しているのでインストール

③./docker/php/Dockerfile を作成する

MacBook-Pro docker-test % touch infra/php/php.ini

スクリーンショット 2021-01-10 17.35.52.png

以下のコードをphp.iniへ

zend.exception_ignore_args = off
expose_php = on
max_execution_time = 30
max_input_vars = 1000
upload_max_filesize = 64M
post_max_size = 128M
memory_limit = 256M
error_reporting = E_ALL
display_errors = on
display_startup_errors = on
log_errors = on
error_log = /dev/stderr
default_charset = UTF-8

[Date]
date.timezone = Asia/Tokyo

[mysqlnd]
mysqlnd.collect_memory_statistics = on

[Assertion]
zend.assertions = 1

[mbstring]
mbstring.language = Japanese

3-4.ウェブサーバー(web)を作る(入れる)

①docker/nginx/default.conf を作成する

MacBook-Pro docker-test % mkdir infra/nginx
MacBook-Pro docker-test % touch infra/nginx/default.conf

スクリーンショット 2021-01-10 17.44.41.png
以下のコードを貼り付ける!!

server {
    listen 80;
    server_name example.com;
    root /work/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_pass app:9000;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

3-5.データベース(db)サーバーを作る(入れる)

①./docker/mysql/Dockerfile を作成する

MacBook-Pro docker-test % mkdir infra/mysql
MacBook-Pro docker-test % touch infra/mysql/Dockerfile

スクリーンショット 2021-01-10 17.58.18.png

以下のコードを貼り付ける!

FROM mysql:8.0

ENV MYSQL_DATABASE=sg_db \
  MYSQL_USER=sg \
  MYSQL_PASSWORD=sg \
  MYSQL_ROOT_PASSWORD=sg \
  TZ=Asia/Tokyo

COPY ./my.cnf /etc/mysql/conf.d/my.cnf
RUN chmod 644 /etc/mysql/conf.d/my.cnf

ここは任意なので好きにしてもらって結構!
データベースを接続するときの名前とパスワードだから
忘れないようにおぼえておこう!

  MYSQL_USER=sg \
  MYSQL_PASSWORD=sg \
  MYSQL_ROOT_PASSWORD=sg \

②docker/mysql/my.cnf を作成する

MacBook-Pro docker-test % touch infra/mysql/my.cnf

スクリーンショット 2021-01-10 17.59.49.png

以下のコードを貼り付ける

[mysqld]
# character set / collation
character_set_server = utf8mb4
collation_server = utf8mb4_0900_ai_ci

# timezone
default-time-zone = SYSTEM
log_timestamps = SYSTEM

# Error Log
log-error = mysql-error.log

# Slow Query Log
slow_query_log = 1
slow_query_log_file = mysql-slow.log
long_query_time = 1.0
log_queries_not_using_indexes = 0

# General Log
general_log = 1
general_log_file = mysql-general.log

[mysql]
default-character-set = utf8mb4

[client]
default-character-set = utf8mb4

これで3つのコンテナが完成!!!!しっかり最終的なディレクトリ構成になりましたか???

3-6.Docker起動!(中身の確認)

①dockerを動かしたいときに使うよ!

MacBook-Pro docker-test % docker-compose up -d --build
・・・・
Successfully built 9813d5181de8
Successfully tagged docker-test_db:latest
Creating docker-test_app_1 ... done
Creating docker-test_db_1  ... done
Creating docker-test_web_1 ... done
MacBook-Pro docker-test % 

上の感じにdoneとでたらそれらはOKということ!
・動かした状態でどう動いてるのか確認!

MacBook-Pro docker-test % docker-compose ps
      Name                     Command               State           Ports        
----------------------------------------------------------------------------------
docker-test_app_1   docker-php-entrypoint php-fpm    Up      9000/tcp             
docker-test_db_1    docker-entrypoint.sh mysqld      Up      3306/tcp, 33060/tcp  
docker-test_web_1   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:10080->80/tcp

ちなみにリスタートしたりしたかったら、一度止めたかったらdown!

MacBook-Pro docker-test % docker-compose down
//一度止めたらまた起動しよう
MacBook-Pro docker-test % docker-compose up -d --build

Dockerに入れたそれぞれサーバー(コンテナ)内に入れたのバージョン確認する方法

・appサーバー

MacBook-Pro docker-test %  docker-compose exec app bash
//PHPのバージョン確認
root@5ce9c9fa1435:/work# php -V
//composerのバージョン確認
root@5ce9c9fa1435:/work# composer -v
//インストール済みの拡張機能一覧の確認
root@5ce9c9fa1435:/work# php -m
//dockerから出る
root@5ce9c9fa1435:/work# exit 

・webサーバー

MacBook-Pro docker-test % docker-compose exec web nginx -v

・DBサーバー

MacBook-Pro docker-test % docker-compose exec db bash
//mysqlのバージョン確認
root@6bcf6de7e31e:/# mysql -V
//dockerから出る
root@6bcf6de7e31e:/work# exit 

これでDocker環境構築終了だ!!!さあLaravelを入れてプログラミングしていきます!!!

定期的にGitコミットはしていったほうがよいですよ!

MacBook-Pro docker-test % git add .
MacBook-Pro docker-test % git commit -m  "laravel commit"
MacBook-Pro docker-test % git push

3-7.Laravelをインストールする(appサーバー上でやります)

①appに入って、Laravelをインストール

MacBook-Pro docker-test % docker-compose exec app bash
root@5ce9c9fa1435:/work# composer create-project --prefer-dist "laravel/laravel=8.*" .
//laravelバージョン確認
root@5ce9c9fa1435:/work# php artisan -V
Laravel Framework 8.21.0
root@5ce9c9fa1435:/work# exit 

②Laravel ウェルカム画面の表示
http://127.0.0.1:10080
にアクセス!!!
スクリーンショット 2021-01-10 18.41.21.png
・VScode確認するとbackendこんな感じになっているはず!
スクリーンショット 2021-01-10 18.44.21.png

3-8.プログラミングしてみる!!(html,blade.phpファイルを作って表示できるか確認!)

HTML(.blade.php)を表示してみよう!!MVCモデルで進めていきます!

①backend/resources/viewsのなかに
helloディレクトリを作成
helloディレクトリの中にhello.blade.phpを作成

スクリーンショット 2021-01-10 18.53.45.png
中身はこれとする。貼り付けてOKです!

<html>
    <body>
        <h1>HELLO Larabel<h1>
    </body>
</html>

②URLから呼び出すコントローラーを設定!
・backend/routes/web.phpを修正
スクリーンショット 2021-01-10 21.01.54.png
以下のコードをbackend/routes/web.phpに追加する!

/// URL/helloのとき「HelloController」を呼び出す
Route::get('hello', 'App\Http\Controllers\HelloController@index');

③backend/app/http/Controllers/の中に
HelloController.phpを作成する

スクリーンショット 2021-01-10 21.06.24.png
以下のコードをbackend/app/http/Controllers/の中に
HelloController.phpに追加する!

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\KrononUser;
use Faker\Provider\ar_JO\Person;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class HelloController extends Controller
{
    public function index()
    {
        return view('hello.hello');
    }
}

④URLにアクセスして表示!!!
http://127.0.0.1:10080/hello
スクリーンショット 2021-01-10 21.45.34.png

3-9.データベースに接続してみる!!!!

ソースコード上で backend/.env のDB接続設定を修正する。
スクリーンショット 2021-01-10 21.54.15.png
①以下のコードに変更!!DBサーバー作った時のに合わせながら!

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=sg_db
DB_USERNAME=sg
DB_PASSWORD=sg

スクリーンショット 2021-01-10 21.57.32.png
②backend/.env.example も同様に変更する

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=sg_db
DB_USERNAME=sg
DB_PASSWORD=sg

ちなみにgitcloneした際はここからやれば動きます

③Laravelインストール

app コンテナにはいってからいろいろ

MacBook-Pro docker-test % docker-compose exec app bash
//コンポーザーをインストールする
root@36ffabe3ffc9:/work# composer install
//.env.exampleを.envファイルにコピーする
root@36ffabe3ffc9:/work# cp .env.example .env
//このコマンドでアプリケーションキーを生成できます。
root@36ffabe3ffc9:/work# php artisan key:generate
Application key set successfully.

//デフォルトで入っているマイグレーションを実行!!デフォルトのテーブルがDBに反映される
root@36ffabe3ffc9:/work# php artisan migrate
Migration table created successfully.
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (40.88ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (37.06ms)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (35.00ms)

これでデフォルトですが、DBにテーブルなどが入りました!!

④データベースの確認(デフォルト)

MacBook-Pro docker-test % docker-compose exec db bash 
//設定したUSERでmysqlにログイン
root@d94d20dd2212:/# mysql -u sg -p
//設定したPASSWORDを入力.envに書いた!!
Enter password: 
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| sg_db              |
+--------------------+
2 rows in set (0.01 sec)
mysql> use sg_db
Database changed
mysql> show tables;
+-----------------+
| Tables_in_sg_db |
+-----------------+
| failed_jobs     |
| migrations      |
| password_resets |
| users           |
+-----------------+

⑤migrationをつくってアプリに反映する!!
スクリーンショット 2021-01-11 13.51.27.png
/backend/database/migration/2021_01_03_090902_create_people_table.php
を作成

※/backend/database/migration/の中にデフォルトでいろいろ入っているからそれをコピーすればいいかも!!
以下のコードを貼り付け!

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePeopleTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('people', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('mail');
            $table->integer('age');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('people');
    }
}

⑥migrationを実行(appコンテナ)の中に入って実行!
appのなかじゃないとdockerにあるDBコンテナに届かない

MacBook-Pro docker-test % docker-compose exec app bash
root@36ffabe3ffc9:/work# php artisan migrate
Migrating: 2021_01_03_090902_create_people_table
Migrated:  2021_01_03_090902_create_people_table (49.03ms)

⑦Seederを作成する!!まずはデフォルトにあるDatabaseSeeder.phpから
"Seederとは??"
ダミーデータ。データベースにコマンドを実行するだけでデータを入れられる!!
スクリーンショット 2021-01-11 14.37.11.png
DatabaseSeeder.phpに以下のソースを貼り付け

$this->call(PeopleTableSeeder::class);

呼び出される側のPeopleTableSeeder.phpを作成
スクリーンショット 2021-01-11 14.40.27.png
PeopleTableSeeder.phpに以下のソースを貼り付け

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class PeopleTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $param = [
            'id' => 1,
            'name' => 'test',
            'mail' => 'test',
            'age' => 20,
        ];
    DB::table('people')->insert($param);
    }

}

⑧Seederを実行する!

MacBook-Pro docker-test % docker-compose exec app bash
root@36ffabe3ffc9:/work# php artisan db:seed
Seeding: Database\Seeders\PeopleTableSeeder
Seeded:  Database\Seeders\PeopleTableSeeder (29.08ms)
Database seeding completed successfully.

これでテーブルはできたし、ダミーデータもできました!あとはweb上で表示すれば完璧ですね!!

データベースに登録されているデータを表示する

①views/hello.blade.phpを作成
スクリーンショット 2021-01-11 14.49.15.png
以下のソースhello.blade.phpを変更

<html>
    <body>
        <h1>HELLO Larabel<h1>
            <h1>DBから表示しているよ<h1>
            <tr><th>Name</th><th>Mail</th><th>Age</th></tr>
                <br>
                @foreach ($items as $item)
                <tr>
                    <td>{{$item -> name}}</td>
                    <td>{{$item -> mail}}</td>
                    <td>{{$item -> age}}</td>
                </tr>
            @endforeach
    </body>
</html>

②Controllers/HelloController.phpを変更
スクリーンショット 2021-01-11 14.50.24.png
以下のソースに変更する

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\KrononUser;
use Faker\Provider\ar_JO\Person;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class HelloController extends Controller
{
    public function index()
    {
        $items = DB::table('people')->get();
        return view('hello.hello',['items' => $items]);
    }
}

③作成したアプリにアクセス!!
http://127.0.0.1:10080/hello
スクリーンショット 2021-01-11 14.53.14.png
これでDBさきほどSeederでいれたダミーデータが表示されていたら完璧ですね!!!
最後にcommmitして終了!!!

MacBook-Pro docker-test % git add .
MacBook-Pro docker-test % git commit -m "db complete"
MacBook-Pro docker-test % git push

あとはこれを世の中に出すためAWSを使えればOK!!!
次回にご期待!!

お疲れ様でした

こういった環境構築かなり疲れますよねーもうへとへとです
全体像を確認したければこちら
【ギリ初心者向け】Laravel Docker AWS(EC2) Webアプリ(PHP)を0から簡単にデプロイする方法(無料)① ー全体像編ー
https://qiita.com/SG_Sg/items/6b8ce48567b6b6602805
次回は③
【ギリ初心者向け】Laravel Docker AWS(EC2) Webアプリ(PHP)を0から簡単にデプロイする方法(無料)③ ーEC2にデプロイ編ー
を予定してます。

参考文献

【超入門】20分でLaravel開発環境を爆速構築するDockerハンズオン
https://qiita.com/ucan-lab/items/56c9dc3cf2e6762672f4
↑の方の記事めちゃくちゃわかりやすいし、細かく書いてあるのでこちらも参考にしていただければ
特に最初の初期設定の情報のまとまりがすばらしいです。この記事の上位互換。

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

Apache 設定後、PHPが動作しない時の対処法

PHPが動作しなくなった時の解決方法をメモで記載しました。

環境

macOS Catalina
Apache 2.4.43 (Unix)
PHP バージョン7.2

背景

macにデフォルトであるApacheを停止し、
Homebrew で新たに Apache httpd をインストールして環境を構築したかった。

Apache の設定ファイルをいぢった後、PHPのバージョンを確認したら以下のエラー文で怒られました。

$ php -v 

dyld: Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib

下記URLの記事を参考にして、コマンドを実行しても解決しなかったので別の方法を試しました。

参考記事

Calling `brew switch` is disabled! Use `brew link` @-versioned formulae instead.

解決方法

先ずは Homebrewに悪いところがないか お医者さんに見てもらう。

$ brew doctor

そうすると以下の文章が表示されました。

Some installed formulae are deprecated or disabled. 
・・・
php@7.2

インストールしたformulae(パッケージ)が非推奨もしくは無効らしい。
私の場合、php@7.2 を下記コマンドでアンインストール。

$ brew uninstall php@7.2

インストールするPHPを検索

$ brew search php

そしてインストール

$ brew install php@7.2

インストールしたらパスを通し、紐付ける。

$ export PATH="/usr/local/opt/php@7.2/bin:$PATH
$ brew link php72

意図したバージョンが表示されるか確認

$ php -v

Apache を再起動

$ sudo apachectl restart

ターミナルを再起動すると、動きました。

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

【PHP 初級】配列を使いこなす➀ ~宣言・初期化・追加・結合・削除~

JAVAエンジニアの私が初めてPHPを使いながら気になったことなどを色々まとめてみました。
そのため、内容はPHP初心者向けになっております。

PHPの配列

基本的にはJAVAの配列(Array)と同じ感じで使えますが、PHPにはJAVAで言うMapの概念がありません。
その代わりにkey=>value連想配列を使用します。

PHPでは配列をよく使うことになるため、配列を操作する数多くのメソッドが用意されています。
ここでは配列に関する基礎知識から色んなメソッドの使い方も見ていきます。

宣言

配列はarray()[](※PHP5.4以降)で宣言します。
個人的には[]での宣言を好みます。

php > $list1 = array();
php > $list2 = [];

// 値の確認はvar_dump, var_export, print_rなどを使います。
php > var_dump($list1);
array(0) {
}
php > print_r($list2);
Array
(
)

初期化

配列

配列の初期化は以下のように行います。

php > $list1 = array(100, 200, 300);
// 代入する値の型は混在も可能です。数値、文字列、配列、オブジェクトなど
php > $list2 = [100, 'a', [], new stdClass];

php > var_export($list1);
array (
  0 => 100,
  1 => 200,
  2 => 300,
)
php > var_dump($list2);
array(4) {
  [0]=>
  int(100)
  [1]=>
  string(1) "a"
  [2]=>
  array(0) {
  }
  [3]=>
  object(stdClass)#1 (0) {
  }
}

連想配列

連想配列はkey=>valueの形で初期化します。

php > $list3 = ['key1'=>100, 'key2'=>200, 'key3'=>300];

php > var_export($list3);
array (
  'key1' => 100,
  'key2' => 200,
  'key3' => 300,
)

値の追加

配列

配列に値を追加する場合は[]array_pushを使います。

[]

[]は値を1つしか追加できません。
foreachなどループ内で値を追加する時によく使われます。

php > $list1 = [100];
php > $list1[] = 200;

php > var_export($list1);
array (
  0 => 100,
  1 => 200,
)

array_push

https://www.php.net/manual/ja/function.array-push.php

array_push (配列 , 追加する値...)
戻り値:追加後の配列のサイズ

array_pushは複数の値を1度に追加することができます。

php > $list1 = [];
php > array_push($list1, 'a', 'b', 'c');

php > var_export($list1);
array (
  0 => 'a',
  1 => 'b',
  2 => 'c',
)

連想配列

連想配列に値を追加する場合は[]を使います。

[]

[]にキーを指定して値を追加します。

php > $list1 = ['key1' => 100];
php > $list1['key2'] = 200;

php > var_export($list1);
array (
  'key1' => 100,
  'key2' => 200,
)

配列の結合

配列の結合には+演算子array_mergearray_merge_recursiveを使います。

配列

+演算子

同じインデックス番号の値は基となる前の配列の値が使われます。
それ以外の値は追加されて結合されます。

php > $list1 = ['a', 'b'];
php > $list2 = $list1 + ['c', 'd', 'e'];

// インデックス'0', '1'は重複するため、前の'a', 'b'が使われます。
// インデックス'2'は基の配列には存在しないため、'e'が追加で結合されます。
php > var_export($list2);
array (
  0 => 'a',
  1 => 'b',
  2 => 'e',
)

array_merge

https://www.php.net/manual/ja/function.array-merge.php

array_merge (結合する配列...)
戻り値:結合した配列

配列の場合、インデックス番号が連番で追加されて結合されます。

php > $list1 = ['a', 'b'];
php > $list2 = array_merge($list1, ['c', 'd', 'e']);

php > var_export($list2);
array (
  0 => 'a',
  1 => 'b',
  2 => 'c',
  3 => 'd',
  4 => 'e',
)

array_merge_recursive

https://www.php.net/manual/ja/function.array-merge-recursive.php

array_merge_recursive (結合する配列...)
戻り値:結合した配列

array_merge_recursiveは配列を再帰的に結合します。
array_merge_recursiveは連想配列の結合において意味があり、配列の場合はarray_mergeと同じ結果になります。

php > $list1 = ['red', 'pink', 'blue'];
php > $list2 = ['green', 'yellow'];
php > $list3 = array_merge_recursive($list1, $list2);

// 数値のインデックスが順番に並んで結合される
php > var_export($list3);
array (
  0 => 'red',
  1 => 'pink',
  2 => 'blue',
  3 => 'green',
  4 => 'yellow',
)

連想配列

+演算子

php > $list1 = ['key1' => 100];
php > $list2 = ['key2' => 200];
php > $list3 = $list1 + $list2;

php > var_export($list3);
array (
  'key1' => 100,
  'key2' => 200,
)

もしキーが重複する場合は配列の結合と同じく、基となる配列の値が残ります。

php > $list1 = ['key1' => 100];
php > $list2 = ['key1' => 200];
php > $list3 = $list1 + $list2;

// 100がそのまま残る
php > var_export($list3);
array (
  'key1' => 100,
)

array_merge

https://www.php.net/manual/ja/function.array-merge.php

array_merge (結合する配列...)
戻り値:結合した配列

php > $list1 = ['key1' => 100];
php > $list2 = ['key2' => 200];
php > $list3 = array_merge($list1, $list2);

php > var_export($list3);
array (
  'key1' => 100,
  'key2' => 200,
)

もしキーが重複する場合は+演算子と違い、結合する配列の値で上書きされます。

php > $list1 = ['key1' => 100];
php > $list2 = ['key1' => 200];
php > $list3 = array_merge($list1, $list2);

// 200に上書きされる
php > var_export($list3);
array (
  'key1' => 200,
)

array_merge_recursive

https://www.php.net/manual/ja/function.array-merge-recursive.php

array_merge_recursive (結合する配列...)
戻り値:結合した配列

array_merge_recursiveは配列を再帰的に結合します。
array_mergeは文字列のキーが重複した場合に値を上書きしますが、array_merge_recursiveは同じキーの値を一つにまとめます。

php > $list1 = ['color1' => 'red', 'color2' => 'pink', 'color4' => 'blue'];
php > $list2 = ['color1' => 'green', 'color3' => 'yellow'];
php > $list3 = array_merge_recursive($list1, $list2);

// キー'color1'は$list1と$list2両方にあるので、値が一つにまとめられる
php > var_export($list3);
array (
  'color1' =>
  array (
    0 => 'red',
    1 => 'green',
  ),
  'color2' => 'pink',
  'color4' => 'blue',
  'color3' => 'yellow',
)

値の削除

配列から値を削除するにはunset, array_splice, array_shift, array_pop, array_diffを使えます。

unset

https://www.php.net/manual/ja/function.unset.php

unset (配列, 削除する値のキー)
戻り値:なし

キーを指定して値を削除します。

php > $list1 = ['red', 'green', 'blue', 'black'];
php > unset($list1[1]); // greenを削除

php > var_export($list1);
array (
  0 => 'red',
  2 => 'blue',
  3 => 'black',
)

結果のインデックスに注意してください。
unsetで削除した場合、インデックス番号は詰め直してくれないため、「1」番が空いている配列になります。
うっかり忘れてしまうとバグの原因になりますので、必ずarray_valuesを使ってインデックスを詰めてあげましょう。
https://www.php.net/manual/ja/function.array-values.php

array_values (配列)
戻り値:配列

php > var_export($list1);
array (
  0 => 'red',
  2 => 'blue', // 「1」番が空いている
  3 => 'black',
)
php > $list1 = array_values($list1);

php > var_export($list1);
array (
  0 => 'red',
  1 => 'blue',
  2 => 'black',
)

連想配列も同じくキーを指定することで値を削除できます。

また、キーを指定しないでリストをそのまま渡すと、リスト自体の削除ができます。
削除したリストはNULLになります。

php > $list1 = ['red', 'green', 'blue', 'black'];
php > unset($list1);

php > var_dump($list1);
NULL

array_splice

https://www.php.net/manual/ja/function.array-splice.php

array_splice (配列, 開始位置, 削除する数)
戻り値:削除した値の配列

範囲を指定して配列の一部を切り取ります。
第2引数で切り取り開始位置を指定、第3引数でいくつ切り取るかを指定します。

php > $list1 = ['red', 'green', 'blue', 'black'];
php > array_splice($list1, 0, 2); // 最初から2つ切り取る

php > var_export($list1);
array (
  0 => 'blue',
  1 => 'black',
)

unsetとは違い、インデックス番号は自動で詰められます。

第3引数を指定しない場合、開始位置より後ろの値を全て削除します。

php > $list1 = ['red', 'green', 'blue', 'black'];
php > array_splice($list1, 1); // 1番目から全て削除する

php > var_export($list1);
array (
  0 => 'red',
)

array_shift

https://www.php.net/manual/ja/function.array-shift.php

array_shift (配列)
戻り値:配列の最初の値

array_shiftは配列の最初の値を切り取ります。

php > $list1 = ['tokyo', 'osaka', 'nagoya'];
php > array_shift($list1);

php > var_export($list1);
array (
  0 => 'osaka',
  1 => 'nagoya',
)

インデックス番号は自動で詰められます。

array_pop

https://www.php.net/manual/ja/function.array-pop.php

array_pop (配列)
戻り値:配列の最後の値

array_popは配列の最後の値を切り取ります。

php > $list1 = ['tokyo', 'osaka', 'nagoya'];
php > array_pop($list1);

php > var_export($list1);
array (
  0 => 'tokyo',
  1 => 'osaka',
)

array_diff

https://www.php.net/manual/ja/function.array-diff.php

array_diff (配列, 比較する配列)
戻り値:比較した結果の配列

array_diffは配列同士を比較して差分を取るメソッドです。
第1引数に指定した配列の値の中で、比較対象の配列には存在しない値を返します。
特定の値のみを全て削除したい場合に使えます。

php > $list1 = ['tokyo', 'osaka', 'nagoya', 'kyoto', 'osaka'];
php > $list1 = array_diff($list1, ['osaka']); // 削除する値を配列で渡す

php > var_export($list1);
array (
  0 => 'tokyo',
  2 => 'nagoya',
  3 => 'kyoto',
)

unsetと同じくarray_valuesでインデックス番号の詰め直しが必要です。

array_diffはメソッド名から「差分を取る」と解釈されるため、そのまま使うと「差分を取りたい」のか、「値を削除したい」のか意図がパッと見てわかりづらいです。
削除として使いたい場合は、意図が分かりやすい名前でラップして使うと良いです。

function remove_values($list, $target) {
    return array_diff($list, [$target]);
}

$list1 = ['apple', 'banana', null, 'orange'];
// メソッドの中身に関係なく「削除」の意図が読み取れる
$list2 = remove_values($list1, null);

var_export($list2);
array (
  0 => 'apple',
  1 => 'banana',
  3 => 'orange',
)

まとめ

ここまで配列の宣言から削除まで、基本的な使い方をまとめました。
思ったより長くなってしまったので、後は別記事にしようと思います。
次は配列から値を抽出、検索する方法など、もう少し実務的な内容をまとめて行こうと思います。

参考にしたサイト

PHP公式サイト
PHPで配列に要素を追加する方法
【PHP】連想配列、配列への追加

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

【PHP 初級】配列を使いこなす ~宣言・初期化・追加・結合・削除~

JAVAエンジニアの私が初めてPHPを使いながら気になったことなどを色々まとめてみました。
そのため、内容はPHP初心者向けになっております。

PHPの配列

基本的にはJAVAの配列(Array)と同じ感じで使えますが、PHPにはJAVAで言うMapの概念がありません。
その代わりにkey=>value連想配列を使用します。

PHPでは配列をよく使うことになるため、配列を操作する数多くのメソッドが用意されています。
ここでは配列に関する基礎知識から色んなメソッドの使い方も見ていきます。

宣言

配列はarray()[](※PHP5.4以降)で宣言します。
個人的には[]での宣言を好みます。

php > $list1 = array();
php > $list2 = [];

// 値の確認はvar_dump, var_export, print_rなどを使います。
php > var_dump($list1);
array(0) {
}
php > print_r($list2);
Array
(
)

初期化

配列

配列の初期化は以下のように行います。

php > $list1 = array(100, 200, 300);
// 代入する値の型は混在も可能です。数値、文字列、配列、オブジェクトなど
php > $list2 = [100, 'a', [], new stdClass];

php > var_export($list1);
array (
  0 => 100,
  1 => 200,
  2 => 300,
)
php > var_dump($list2);
array(4) {
  [0]=>
  int(100)
  [1]=>
  string(1) "a"
  [2]=>
  array(0) {
  }
  [3]=>
  object(stdClass)#1 (0) {
  }
}

連想配列

連想配列はkey=>valueの形で初期化します。

php > $list3 = ['key1'=>100, 'key2'=>200, 'key3'=>300];

php > var_export($list3);
array (
  'key1' => 100,
  'key2' => 200,
  'key3' => 300,
)

値の追加

配列

配列に値を追加する場合は[]array_pushを使います。

[]

[]は値を1つしか追加できません。
foreachなどループ内で値を追加する時によく使われます。

php > $list1 = [100];
php > $list1[] = 200;

php > var_export($list1);
array (
  0 => 100,
  1 => 200,
)

array_push

https://www.php.net/manual/ja/function.array-push.php

array_push (配列 , 追加する値...)
戻り値:追加後の配列のサイズ

array_pushは複数の値を1度に追加することができます。

php > $list1 = [];
php > array_push($list1, 'a', 'b', 'c');

php > var_export($list1);
array (
  0 => 'a',
  1 => 'b',
  2 => 'c',
)

連想配列

連想配列に値を追加する場合は[]を使います。

[]

[]にキーを指定して値を追加します。

php > $list1 = ['key1' => 100];
php > $list1['key2'] = 200;

php > var_export($list1);
array (
  'key1' => 100,
  'key2' => 200,
)

配列の結合

配列の結合には+演算子array_mergearray_merge_recursiveを使います。

配列

+演算子

同じインデックス番号の値は基となる前の配列の値が使われます。
それ以外の値は追加されて結合されます。

php > $list1 = ['a', 'b'];
php > $list2 = $list1 + ['c', 'd', 'e'];

// インデックス'0', '1'は重複するため、前の'a', 'b'が使われます。
// インデックス'2'は基の配列には存在しないため、'e'が追加で結合されます。
php > var_export($list2);
array (
  0 => 'a',
  1 => 'b',
  2 => 'e',
)

array_merge

https://www.php.net/manual/ja/function.array-merge.php

array_merge (結合する配列...)
戻り値:結合した配列

配列の場合、インデックス番号が連番で追加されて結合されます。

php > $list1 = ['a', 'b'];
php > $list2 = array_merge($list1, ['c', 'd', 'e']);

php > var_export($list2);
array (
  0 => 'a',
  1 => 'b',
  2 => 'c',
  3 => 'd',
  4 => 'e',
)

array_merge_recursive

https://www.php.net/manual/ja/function.array-merge-recursive.php

array_merge_recursive (結合する配列...)
戻り値:結合した配列

array_merge_recursiveは配列を再帰的に結合します。
array_merge_recursiveは連想配列の結合において意味があり、配列の場合はarray_mergeと同じ結果になります。

php > $list1 = ['red', 'pink', 'blue'];
php > $list2 = ['green', 'yellow'];
php > $list3 = array_merge_recursive($list1, $list2);

// 数値のインデックスが順番に並んで結合される
php > var_export($list3);
array (
  0 => 'red',
  1 => 'pink',
  2 => 'blue',
  3 => 'green',
  4 => 'yellow',
)

連想配列

+演算子

php > $list1 = ['key1' => 100];
php > $list2 = ['key2' => 200];
php > $list3 = $list1 + $list2;

php > var_export($list3);
array (
  'key1' => 100,
  'key2' => 200,
)

もしキーが重複する場合は配列の結合と同じく、基となる配列の値が残ります。

php > $list1 = ['key1' => 100];
php > $list2 = ['key1' => 200];
php > $list3 = $list1 + $list2;

// 100がそのまま残る
php > var_export($list3);
array (
  'key1' => 100,
)

array_merge

https://www.php.net/manual/ja/function.array-merge.php

array_merge (結合する配列...)
戻り値:結合した配列

php > $list1 = ['key1' => 100];
php > $list2 = ['key2' => 200];
php > $list3 = array_merge($list1, $list2);

php > var_export($list3);
array (
  'key1' => 100,
  'key2' => 200,
)

もしキーが重複する場合は+演算子と違い、結合する配列の値で上書きされます。

php > $list1 = ['key1' => 100];
php > $list2 = ['key1' => 200];
php > $list3 = array_merge($list1, $list2);

// 200に上書きされる
php > var_export($list3);
array (
  'key1' => 200,
)

array_merge_recursive

https://www.php.net/manual/ja/function.array-merge-recursive.php

array_merge_recursive (結合する配列...)
戻り値:結合した配列

array_merge_recursiveは配列を再帰的に結合します。
array_mergeは文字列のキーが重複した場合に値を上書きしますが、array_merge_recursiveは同じキーの値を一つにまとめます。

php > $list1 = ['color1' => 'red', 'color2' => 'pink', 'color4' => 'blue'];
php > $list2 = ['color1' => 'green', 'color3' => 'yellow'];
php > $list3 = array_merge_recursive($list1, $list2);

// キー'color1'は$list1と$list2両方にあるので、値が一つにまとめられる
php > var_export($list3);
array (
  'color1' =>
  array (
    0 => 'red',
    1 => 'green',
  ),
  'color2' => 'pink',
  'color4' => 'blue',
  'color3' => 'yellow',
)

値の削除

配列から値を削除するにはunset, array_splice, array_shift, array_pop, array_diffを使えます。

unset

https://www.php.net/manual/ja/function.unset.php

unset (配列, 削除する値のキー)
戻り値:なし

キーを指定して値を削除します。

php > $list1 = ['red', 'green', 'blue', 'black'];
php > unset($list1[1]); // greenを削除

php > var_export($list1);
array (
  0 => 'red',
  2 => 'blue',
  3 => 'black',
)

結果のインデックスに注意してください。
unsetで削除した場合、インデックス番号は詰め直してくれないため、「1」番が空いている配列になります。
うっかり忘れてしまうとバグの原因になりますので、必ずarray_valuesを使ってインデックスを詰めてあげましょう。
https://www.php.net/manual/ja/function.array-values.php

array_values (配列)
戻り値:配列

php > var_export($list1);
array (
  0 => 'red',
  2 => 'blue', // 「1」番が空いている
  3 => 'black',
)
php > $list1 = array_values($list1);

php > var_export($list1);
array (
  0 => 'red',
  1 => 'blue',
  2 => 'black',
)

連想配列も同じくキーを指定することで値を削除できます。

また、キーを指定しないでリストをそのまま渡すと、リスト自体の削除ができます。
削除したリストはNULLになります。

php > $list1 = ['red', 'green', 'blue', 'black'];
php > unset($list1);

php > var_dump($list1);
NULL

array_splice

https://www.php.net/manual/ja/function.array-splice.php

array_splice (配列, 開始位置, 削除する数)
戻り値:削除した値の配列

範囲を指定して配列の一部を切り取ります。
第2引数で切り取り開始位置を指定、第3引数でいくつ切り取るかを指定します。

php > $list1 = ['red', 'green', 'blue', 'black'];
php > array_splice($list1, 0, 2); // 最初から2つ切り取る

php > var_export($list1);
array (
  0 => 'blue',
  1 => 'black',
)

unsetとは違い、インデックス番号は自動で詰められます。

第3引数を指定しない場合、開始位置より後ろの値を全て削除します。

php > $list1 = ['red', 'green', 'blue', 'black'];
php > array_splice($list1, 1); // 1番目から全て削除する

php > var_export($list1);
array (
  0 => 'red',
)

array_shift

https://www.php.net/manual/ja/function.array-shift.php

array_shift (配列)
戻り値:配列の最初の値

array_shiftは配列の最初の値を切り取ります。

php > $list1 = ['tokyo', 'osaka', 'nagoya'];
php > array_shift($list1);

php > var_export($list1);
array (
  0 => 'osaka',
  1 => 'nagoya',
)

インデックス番号は自動で詰められます。

array_pop

https://www.php.net/manual/ja/function.array-pop.php

array_pop (配列)
戻り値:配列の最後の値

array_popは配列の最後の値を切り取ります。

php > $list1 = ['tokyo', 'osaka', 'nagoya'];
php > array_pop($list1);

php > var_export($list1);
array (
  0 => 'tokyo',
  1 => 'osaka',
)

array_diff

https://www.php.net/manual/ja/function.array-diff.php

array_diff (配列, 比較する配列)
戻り値:比較した結果の配列

array_diffは配列同士を比較して差分を取るメソッドです。
第1引数に指定した配列の値の中で、比較対象の配列には存在しない値を返します。
特定の値のみを全て削除したい場合に使えます。

php > $list1 = ['tokyo', 'osaka', 'nagoya', 'kyoto', 'osaka'];
php > $list1 = array_diff($list1, ['osaka']); // 削除する値を配列で渡す

php > var_export($list1);
array (
  0 => 'tokyo',
  2 => 'nagoya',
  3 => 'kyoto',
)

unsetと同じくarray_valuesでインデックス番号の詰め直しが必要です。

array_diffはメソッド名から「差分を取る」と解釈されるため、そのまま使うと「差分を取りたい」のか、「値を削除したい」のか意図がパッと見てわかりづらいです。
削除として使いたい場合は、意図が分かりやすい名前でラップして使うと良いです。

function remove_values($list, $target) {
    return array_diff($list, [$target]);
}

$list1 = ['apple', 'banana', null, 'orange'];
// メソッドの中身に関係なく「削除」の意図が読み取れる
$list2 = remove_values($list1, null);

var_export($list2);
array (
  0 => 'apple',
  1 => 'banana',
  3 => 'orange',
)

まとめ

ここまで配列の宣言から削除まで、基本的な使い方をまとめました。
思ったより長くなってしまったので、後は別記事にしようと思います。
次は配列から値を抽出、検索する方法など、もう少し実務的な内容をまとめて行こうと思います。

参考にしたサイト

PHP公式サイト
PHPで配列に要素を追加する方法
【PHP】連想配列、配列への追加

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

【PHP】配列を使いこなす➀ ~宣言・初期化・追加・結合・削除~

JAVAエンジニアの私が初めてPHPを使いながら気になったことなどを色々まとめてみました。
そのため、内容はPHP初心者向けになっております。

PHPの配列

基本的にはJAVAの配列(Array)と同じ感じで使えますが、PHPにはJAVAで言うMapの概念がありません。
その代わりにkey=>value連想配列を使用します。

PHPでは配列をよく使うことになるため、配列を操作する数多くのメソッドが用意されています。
ここでは配列に関する基礎知識から色んなメソッドの使い方も見ていきます。

宣言

配列はarray()[](※PHP5.4以降)で宣言します。
個人的には[]での宣言を好みます。

php > $list1 = array();
php > $list2 = [];

// 値の確認はvar_dump, var_export, print_rなどを使います。
php > var_dump($list1);
array(0) {
}
php > print_r($list2);
Array
(
)

初期化

配列

配列の初期化は以下のように行います。

php > $list1 = array(100, 200, 300);
// 代入する値の型は混在も可能です。数値、文字列、配列、オブジェクトなど
php > $list2 = [100, 'a', [], new stdClass];

php > var_export($list1);
array (
  0 => 100,
  1 => 200,
  2 => 300,
)
php > var_dump($list2);
array(4) {
  [0]=>
  int(100)
  [1]=>
  string(1) "a"
  [2]=>
  array(0) {
  }
  [3]=>
  object(stdClass)#1 (0) {
  }
}

連想配列

連想配列はkey=>valueの形で初期化します。

php > $list3 = ['key1'=>100, 'key2'=>200, 'key3'=>300];

php > var_export($list3);
array (
  'key1' => 100,
  'key2' => 200,
  'key3' => 300,
)

値の追加

配列

配列に値を追加する場合は[]array_pushを使います。

[]

[]は値を1つしか追加できません。
foreachなどループ内で値を追加する時によく使われます。

php > $list1 = [100];
php > $list1[] = 200;

php > var_export($list1);
array (
  0 => 100,
  1 => 200,
)

array_push

https://www.php.net/manual/ja/function.array-push.php

array_push (配列 , 追加する値...)
戻り値:追加後の配列のサイズ

array_pushは複数の値を1度に追加することができます。

php > $list1 = [];
php > array_push($list1, 'a', 'b', 'c');

php > var_export($list1);
array (
  0 => 'a',
  1 => 'b',
  2 => 'c',
)

連想配列

連想配列に値を追加する場合は[]を使います。

[]

[]にキーを指定して値を追加します。

php > $list1 = ['key1' => 100];
php > $list1['key2'] = 200;

php > var_export($list1);
array (
  'key1' => 100,
  'key2' => 200,
)

配列の結合

配列の結合には+演算子array_mergearray_merge_recursiveを使います。

配列

+演算子

同じインデックス番号の値は基となる前の配列の値が使われます。
それ以外の値は追加されて結合されます。

php > $list1 = ['a', 'b'];
php > $list2 = $list1 + ['c', 'd', 'e'];

// インデックス'0', '1'は重複するため、前の'a', 'b'が使われます。
// インデックス'2'は基の配列には存在しないため、'e'が追加で結合されます。
php > var_export($list2);
array (
  0 => 'a',
  1 => 'b',
  2 => 'e',
)

array_merge

https://www.php.net/manual/ja/function.array-merge.php

array_merge (結合する配列...)
戻り値:結合した配列

配列の場合、インデックス番号が連番で追加されて結合されます。

php > $list1 = ['a', 'b'];
php > $list2 = array_merge($list1, ['c', 'd', 'e']);

php > var_export($list2);
array (
  0 => 'a',
  1 => 'b',
  2 => 'c',
  3 => 'd',
  4 => 'e',
)

array_merge_recursive

https://www.php.net/manual/ja/function.array-merge-recursive.php

array_merge_recursive (結合する配列...)
戻り値:結合した配列

array_merge_recursiveは配列を再帰的に結合します。
array_merge_recursiveは連想配列の結合において意味があり、配列の場合はarray_mergeと同じ結果になります。

php > $list1 = ['red', 'pink', 'blue'];
php > $list2 = ['green', 'yellow'];
php > $list3 = array_merge_recursive($list1, $list2);

// 数値のインデックスが順番に並んで結合される
php > var_export($list3);
array (
  0 => 'red',
  1 => 'pink',
  2 => 'blue',
  3 => 'green',
  4 => 'yellow',
)

連想配列

+演算子

php > $list1 = ['key1' => 100];
php > $list2 = ['key2' => 200];
php > $list3 = $list1 + $list2;

php > var_export($list3);
array (
  'key1' => 100,
  'key2' => 200,
)

もしキーが重複する場合は配列の結合と同じく、基となる配列の値が残ります。

php > $list1 = ['key1' => 100];
php > $list2 = ['key1' => 200];
php > $list3 = $list1 + $list2;

// 100がそのまま残る
php > var_export($list3);
array (
  'key1' => 100,
)

array_merge

https://www.php.net/manual/ja/function.array-merge.php

array_merge (結合する配列...)
戻り値:結合した配列

php > $list1 = ['key1' => 100];
php > $list2 = ['key2' => 200];
php > $list3 = array_merge($list1, $list2);

php > var_export($list3);
array (
  'key1' => 100,
  'key2' => 200,
)

もしキーが重複する場合は+演算子と違い、結合する配列の値で上書きされます。

php > $list1 = ['key1' => 100];
php > $list2 = ['key1' => 200];
php > $list3 = array_merge($list1, $list2);

// 200に上書きされる
php > var_export($list3);
array (
  'key1' => 200,
)

array_merge_recursive

https://www.php.net/manual/ja/function.array-merge-recursive.php

array_merge_recursive (結合する配列...)
戻り値:結合した配列

array_merge_recursiveは配列を再帰的に結合します。
array_mergeは文字列のキーが重複した場合に値を上書きしますが、array_merge_recursiveは同じキーの値を一つにまとめます。

php > $list1 = ['color1' => 'red', 'color2' => 'pink', 'color4' => 'blue'];
php > $list2 = ['color1' => 'green', 'color3' => 'yellow'];
php > $list3 = array_merge_recursive($list1, $list2);

// キー'color1'は$list1と$list2両方にあるので、値が一つにまとめられる
php > var_export($list3);
array (
  'color1' =>
  array (
    0 => 'red',
    1 => 'green',
  ),
  'color2' => 'pink',
  'color4' => 'blue',
  'color3' => 'yellow',
)

値の削除

配列から値を削除するにはunset, array_splice, array_shift, array_pop, array_diffを使えます。

unset

https://www.php.net/manual/ja/function.unset.php

unset (配列, 削除する値のキー)
戻り値:なし

キーを指定して値を削除します。

php > $list1 = ['red', 'green', 'blue', 'black'];
php > unset($list1[1]); // greenを削除

php > var_export($list1);
array (
  0 => 'red',
  2 => 'blue',
  3 => 'black',
)

結果のインデックスに注意してください。
unsetで削除した場合、インデックス番号は詰め直してくれないため、「1」番が空いている配列になります。
うっかり忘れてしまうとバグの原因になりますので、必ずarray_valuesを使ってインデックスを詰めてあげましょう。
https://www.php.net/manual/ja/function.array-values.php

array_values (配列)
戻り値:配列

php > var_export($list1);
array (
  0 => 'red',
  2 => 'blue', // 「1」番が空いている
  3 => 'black',
)
php > $list1 = array_values($list1);

php > var_export($list1);
array (
  0 => 'red',
  1 => 'blue',
  2 => 'black',
)

連想配列も同じくキーを指定することで値を削除できます。

また、キーを指定しないでリストをそのまま渡すと、リスト自体の削除ができます。
削除したリストはNULLになります。

php > $list1 = ['red', 'green', 'blue', 'black'];
php > unset($list1);

php > var_dump($list1);
NULL

array_splice

https://www.php.net/manual/ja/function.array-splice.php

array_splice (配列, 開始位置, 削除する数)
戻り値:削除した値の配列

範囲を指定して配列の一部を切り取ります。
第2引数で切り取り開始位置を指定、第3引数でいくつ切り取るかを指定します。

php > $list1 = ['red', 'green', 'blue', 'black'];
php > array_splice($list1, 0, 2); // 最初から2つ切り取る

php > var_export($list1);
array (
  0 => 'blue',
  1 => 'black',
)

unsetとは違い、インデックス番号は自動で詰められます。

第3引数を指定しない場合、開始位置より後ろの値を全て削除します。

php > $list1 = ['red', 'green', 'blue', 'black'];
php > array_splice($list1, 1); // 1番目から全て削除する

php > var_export($list1);
array (
  0 => 'red',
)

array_shift

https://www.php.net/manual/ja/function.array-shift.php

array_shift (配列)
戻り値:配列の最初の値

array_shiftは配列の最初の値を切り取ります。

php > $list1 = ['tokyo', 'osaka', 'nagoya'];
php > array_shift($list1);

php > var_export($list1);
array (
  0 => 'osaka',
  1 => 'nagoya',
)

インデックス番号は自動で詰められます。

array_pop

https://www.php.net/manual/ja/function.array-pop.php

array_pop (配列)
戻り値:配列の最後の値

array_popは配列の最後の値を切り取ります。

php > $list1 = ['tokyo', 'osaka', 'nagoya'];
php > array_pop($list1);

php > var_export($list1);
array (
  0 => 'tokyo',
  1 => 'osaka',
)

array_diff

https://www.php.net/manual/ja/function.array-diff.php

array_diff (配列, 比較する配列)
戻り値:比較した結果の配列

array_diffは配列同士を比較して差分を取るメソッドです。
第1引数に指定した配列の値の中で、比較対象の配列には存在しない値を返します。
特定の値のみを全て削除したい場合に使えます。

php > $list1 = ['tokyo', 'osaka', 'nagoya', 'kyoto', 'osaka'];
php > $list1 = array_diff($list1, ['osaka']); // 削除する値を配列で渡す

php > var_export($list1);
array (
  0 => 'tokyo',
  2 => 'nagoya',
  3 => 'kyoto',
)

unsetと同じくarray_valuesでインデックス番号の詰め直しが必要です。

array_diffはメソッド名から「差分を取る」と解釈されるため、そのまま使うと「差分を取りたい」のか、「値を削除したい」のか意図がパッと見てわかりづらいです。
削除として使いたい場合は、意図が分かりやすい名前でラップして使うと良いです。

function remove_values($list, $target) {
    return array_diff($list, [$target]);
}

$list1 = ['apple', 'banana', null, 'orange'];
// メソッドの中身に関係なく「削除」の意図が読み取れる
$list2 = remove_values($list1, null);

var_export($list2);
array (
  0 => 'apple',
  1 => 'banana',
  3 => 'orange',
)

まとめ

ここまで配列の宣言から削除まで、基本的な使い方をまとめました。
思ったより長くなってしまったので、後は別記事にしようと思います。
次は配列から値を抽出、検索する方法など、もう少し実務的な内容をまとめて行こうと思います。

参考にしたサイト

PHP公式サイト
PHPで配列に要素を追加する方法
【PHP】連想配列、配列への追加

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

Qiitaのいろいろランキング2020

はじめに

これまで毎年いろいろランキングを作ってくれていた @t_nakayama0714 氏がお休みになられてしまったのと、といってQiita公式がなんかやってくれたりは特になかったので、無断で勝手に代理作成したものです。
氏はシェル芸を駆使していましたが、私はぺちぱーなので普通にPHPで集計しています。

過去のランキングはこちら。

なお、集計したデータは2021年1月9日あたりのものです。

やること

2019年のやつのほぼパクりです。

  • ユーザ別Contributionランキング
  • ユーザ別記事数ランキング
  • ユーザ別フォロワーランキング
  • 記事別LGTMランキング
  • Organizationsランキング
  • その他分析いろいろ

前準備

とりあえずデータの前準備をしようと思ったのですが、ユーザ一覧ページがなくなったうえにユーザ一覧取得APIはページあたり100人 * 100ページまでしか許されない(つまり最新1万人しか遡れない)ので、ユーザ一覧が作れなくていきなり詰みました。

試しにユーザ一覧取得APIを叩いてみたところ、最新のユーザIDは既に100万を超えていました。
さてどうしようかとAPI一覧を眺めていたら、ユーザIDからユーザ情報を取得するAPIというのがありました。
すなわち、これを1から順に100万回叩けば全ユーザ情報が取れるはずです。

https://qiita.com/api/v2/docs#%E5%88%A9%E7%94%A8%E5%88%B6%E9%99%90

利用制限
認証している状態ではユーザごとに1時間に1000回まで、認証していない状態ではIPアドレスごとに1時間に60回までリクエストを受け付けます。

はい。
全ユーザのリストを取得するだけで一ヶ月以上かかることが判明したので、この手段は使えないようです。

記事ランキングを定期更新しているような人たちであればユーザ情報なども持っていると思いますが、私はそんなもの持ってないので、完全なユーザ一覧の作成は華麗に諦めることにします。

ということで厳密なものではなく、だいたい合ってるだろうランキングを作る方針にします。
具体的には、2019年のContributionランキングと、2020年の殿堂入りに入っているユーザについて集計を行います。
2019年のContributionランキングに入っておらず、2020年の記事が殿堂にひとつも入っていないユーザは、ランキングに影響を及ぼすことはないだろうという推測です。

また、この集計方法の変更に伴い、全ユーザや全記事の集計・統計などはできなくなりました。

そんなわけで方針が決まったので、あとはひたすらユーザページ・記事ページをクロール & スクレイピングしていくだけです
しめやかにsleep()を入れ忘れて爆発四散。

ユーザ分析

ユーザの各種ランキングです。
上記のとおり、残念ながら全ユーザ数やContribution分布などは作れません。

ユーザContributionランキング

ユーザごとのContribution数ランキングです。

ランク 前年比 ユーザ名 総Contribution 前年比 記事数 平均LGTM ピックアップ
1 0 @jnchito 63936 +10094 279 229.16 [初心者向け] RubyやRailsでリファクタリングに使えそうなイディオムとか便利メソッドとか
2 +1 @rana_kualu 53573 +14344 434 123.44 放課後アトリエといろ 第65535話が公開された
3 -1 @hirokidaichi 53166 +4151 45 1181.47 開発チームの生産性・健全性を客観的に知るためにリポジトリ履歴から機械的に可視化するツールを作った
4 0 @suin 50141 +10959 1176 42.64 JavaScript: 通常の関数とアロー関数の違いは「書き方だけ」ではない。異なる性質が10個ほどある。
5 0 @icoxfog417 38828 +1857 155 250.5
6 +7 @Yametaro 35577 +18640 69 515.61 4歳娘「パパ、セッションとCookieってなあに?」
7 +1 @drken 35489 +13144 51 695.86 AtCoder に登録したら次にやること ~ これだけ解けば十分闘える!過去問精選 10 問 ~
8 @mpyw 28792 312 92.28 【Laravel】 MySQL がマスタスレーブ構成のとき,リクエストを超えて sticky 効果を適用する
9 -3 @opengl-8080 27205 +2871 280 97.16
10 -3 @mizchi 24938 +1245 268 93.05
11 +12 @baby-degu 22372 +8219 76 294.37
12 -1 @youwht 21283 +2367 44 483.7 「赤の他人」の対義語は「白い恋人」 これを自動生成したい物語
13 -4 @KeithYokoma 21266 +572 143 148.71
14 +10 @uhyo 20908 +7027 75 278.77 TypeScriptの型入門
15 -5 @yuku_t 19681 +32 205 96
16 +12 @TakahikoKawasaki 18673 +5865 47 397.3
17 -5 @awakia 18673 +405 156 119.7
18 -3 @shibukawa 18545 +2256 140 132.46
19 0 @poly_soft 17265 +1752 44 392.39 2018年の最先端バックエンドエンジニアに必要なスキルについて考えてみました。
20 -3 @koher 17177 +1455 76 226.01 なぜSwiftのプロトコルはジェネリクスをサポートしないのか
21 -7 @b4b4r07 17106 +658 57 300.11
22 -6 @edo_m18 16785 +765 413 40.64
23 -5 @zaru 16688 +970 157 106.29
24 -3 @kenmatsu4 15943 +1194 72 221.43
25 -5 @cognitom 15511 +116 98 158.28
26 @ryuichi1208 14750 119 123.95 よく使うcurlコマンドのオプション
27 -2 @tag1216 14589 +1186 122 119.58 QiitaトレンドをリニューアルしてQiiTrendを作った
28 +8 @teradonburi 14487 +2619 131 110.59 【保存版】Webフロントエンド基礎力(初心者向け)
29 -7 @haminiku 14416 -6 76 189.68
30 -4 @takeharu 14332 +979 18 796.22
31 +22 @soarflat 14321 +4240 28 511.46 webpack 4 入門
32 +9 @alt 14009 +2845 0 -
33 -6 @tonkotsuboy_com 13870 +1004 114 121.67 GitHubのmasterブランチをWebページとして公開する手順(GitHub Pages)
34 -3 @t_nakayama0714 13803 +1416 42 328.64 不思議の国のSE用語
35 +12 @zembutsu 13315 +2638 140 95.11 Jitsi Meet(ビデオ会議システム)のサーバを Docker Compose で起動する手順
36 -4 @tadsan 13158 +818 205 64.19
37 +6 @Qiita 13152 +2019 5 2630.4
38 +24 @gold-kou 13116 +3691 48 273.25 いまさらだけどDockerに入門したので分かりやすくまとめてみた
39 -4 @Hironsan 12831 +952 51 251.59
40 @ucan-lab 12631 174 72.59 Laravel × Dacapo で始める快適マイグレーション生活!
41 +22 @zaburo 12573 +3200 441 28.51
42 -9 @yimajo 12501 +250 182 68.69 Swiftでビジネスロジックを実行するUseCaseのprotocolを作りたい話 2019
43 -13 @susieyy 12392 -15 51 242.98 iOSリバーシリファクタリングチャレンジ w/ Redux
44 -7 @ynakayama 12344 +489 201 61.41
45 -16 @kazunori279 12299 -179 44 279.52
46 -8 @hshimo 12149 +329 310 39.19
47 +11 @shizuma 11964 +2284 109 109.76 GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~
48 -8 @uasi 11906 +337 125 95.25
49 -15 @appwatcher 11899 -225 60 198.32
50 -11 @kawasima 11898 +179 83 143.35
51 -9 @hkusu 11542 +408 233 49.54
52 0 @jabba 11469 +1097 35 327.69 技術書ランキングサイトをQiita記事の集計から作ったら、約4000冊の技術本がいい感じに並んだ
53 -5 @howdy39 11449 +808 74 154.72
54 -10 @kidach1 11418 +339 85 134.33
55 -10 @tukiyo3 11338 +548 1791 6.33 自分の投稿のリンク集
56 +10 @kaityo256 11205 +2203 300 37.35 mallocの動作を追いかける(mmap編)
57 -7 @kazukichi 11191 +580 52 215.21
58 -4 @tbpgr 11153 +1218 756 14.75 GitHub Flow 図解
59 -13 @Quramy 11063 +341 102 108.46
60 +7 @Ted-HM 10968 +2235 16 685.5
61 -12 @joker1007 10591 -24 106 99.92
62 -1 @n0bisuke 10391 +934 451 23.04 1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 #nodefest
63 -7 @y_hokkey 10199 +427 72 141.65 実装を引き受ける前に詰めておくべきWebフロントエンドの想定漏れチェックシート
64 -4 @tmknom 10188 +626 12 849 AWSアカウントを取得したら速攻でやっておくべき初期設定まとめ
65 -10 @amay077 10170 +374 352 28.89
66 -9 @kawaz 10143 +394 159 63.79
67 @omiita 10081 25 403.24 【2020決定版】スーパーわかりやすい最適化アルゴリズム -損失関数からAdamとニュートン法-
68 @ulwlu 10046 12 837.17
69 +5 @shuntaro_tamura 9978 +1824 66 151.18
70 +22 @naoki_mochizuki 9685 +2481 18 538.06
71 -12 @vvakame 9620 +52 62 155.16
72 @ryo2132 9556 143 66.83 正式リリース前に総予習!! Vue3の変更点まとめ
73 -3 @mima_ita 9416 +1014 164 57.41 公式ドキュメントが読まれない こんな世の中じゃ ポイズン
74 -3 @tenntenn 9387 +1051 80 117.34
75 -6 @takahirom 9386 +932 146 64.29
76 -4 @pugiemonn 9373 +1158 285 32.89 レガシー開発環境を今風の開発に近づけるために一年やってきたこと
77 +12 @koshian2 9242 +1952 124 74.53 Inpaintingからディープラーニング、最新のGAN事情について学べる本を書いた
78 -27 @usagimaru 9242 -1244 175 52.81
79 @rubytomato@github 9183 216 42.51
80 -15 @okappy 9125 +119 29 314.66
81 -17 @sion_cojp 9107 +18 42 216.83
82 +2 @toshihirock 9073 +1480 278 32.64
83 -4 @nonbiri15 8884 +989 343 25.9 優秀な技術者を追い出してしまう方法
84 +12 @toRisouP 8872 +2133 101 87.84
85 @tomo_makes 8829 32 275.91 【秒速で無料GPUを使う】深層学習実践Tips on Colaboratory
86 @kahirokunn 8736 111 78.7 A brief look at Atomic Components[和訳]
87 -14 @jacksuzuki 8710 +506 10 871 ロシアの天才ハッカーによる【新人エンジニアサバイバルガイド】
88 -20 @syui 8655 +142 276 31.36
89 -7 @mochizukikotaro 8457 +647 314 26.93
90 +5 @MahoTakara 8430 +1661 307 27.46 Argo Rollouts + Istio を連携してトラフィックシェーピングによるカナリアリリース
91 +6 @kaizen_nagoya 8284 +1586 2487 3.33 プログラマが知っているとよい色使い(JIS安全色)
92 -7 @potato4d 8260 +759 59 140
93 -10 @disc99 8128 +430 29 280.28
94 -14 @terrierscript 8125 +270 139 58.45
95 -18 @KanNishida 8095 +152 79 102.47
96 @yuno_miyako 8076 26 310.62
97 -21 @tatesuke 8044 +90 41 196.2
98 -23 @yuya_presto 8024 -4 40 200.6
99 -1 @ritukiii 7961 +1316 117 68.04
100 -10 @nekoneko-wanwan 7927 +638 57 139.07

一位は2017年から安定して独走している @jnchito さんです。
おめでとうございます。
今後彼の寝首を掻く人は現れるのでしょうか。

Contribution数の増加が最も多かったのは @Yametaro さんで、+18640となっています。
もし昨年始めいてたとしても、いきなり18位に入るくらいの勢いですね。

昨年ランク内にいたうち、今年の上昇幅が最も大きかったのは62位から38位へ+24上昇した @gold-kou さんでした。
おめでとうございます。

新たなランクインは10名です。
新人賞は @mpyw さんで、3万近いLGTMを稼いでいきなり8位に登場です。
おめでとうございます!
……あれ?
この人だいぶ前からいなかったっけ?

と調べてみたら、2018年のランキングにはいたのに2019年のランキングで抜け落ちていたみたいです。
いったいどうしてこうなった。

というわけで本当の新人賞は @ryuichi1208 さん……君も2018年おったやんけ。
というわけで三度目の正直、本当の新人賞は @ucan-lab さんでした。
おめでとうございます。
2018年に活動開始し、主にVSCodeLaravelの記事を書かれているようです。

ちなみに昨年の上位100名のうち、今年退会した人はいないようでした。
例の問題は意外と深刻な影響はなかったようです。
もちろん影響が完全にゼロというわけではなく、29位 @haminiku さん、43位 @susieyy さんなどは累計LGTM数が減少するという珍しい結果になっています。
というか78位 @usagimaru さんの-1244ってなに?
さすがにこれは記事を削除したとかの別の原因だと思われます。

ユーザ記事数ランキング

記事数のランキングです。

ランク 前年比 ユーザ名 記事数 前年比 Contribution数
1 0 @7of9 6163 +84 5529
2 0 @kaizen_nagoya 2487 +263 8284
3 0 @YumaInaura 2189 +253 6685
4 +1 @ohisama@github 1940 +541 717
5 -1 @tukiyo3 1791 +117 11338
6 0 @suin 1176 +105 50141
7 +1 @ekzemplaro 1012 +376 1703
8 -1 @tbpgr 756 +4 11153
9 @miriwo 635 2163
10 +4 @Q11Q 465 +71 574
11 -2 @chen7897499 457 0 80
12 +3 @n0bisuke 451 +60 10391
13 -3 @zaburo 441 +29 12573
14 @rana_kualu 434 53573
15 -2 @Nabetani 426 +27 1893
16 -4 @jkr_2255 417 +14 6682
17 +2 @cielavenir 413 +35 915
18 -7 @edo_m18 413 +8 16785
19 -3 @snaka 405 +17 3993
20 -3 @tcsh 389 +2 1483

新人賞にして最多投稿賞は @miriwo さんです。
2020年7月には1年間毎日投稿するという偉業を成し遂げ、さらにその後もほぼ毎日投稿を続けているようです。
あとなんか私がランクインしていますが、私は毎週月曜日にしか投稿していないので、そんなに多かったか?って感じます。

ユーザフォロワー数ランキング

どれだけウォッチされているかのランキングです。

ランク 前年比 ユーザ名 フォロワー数 前年比 Contribution数
1 +3 @Yametaro 5435 +2471 35577
2 -1 @jnchito 4847 +817 63936
3 -1 @kaizen_nagoya 4361 +458 8284
4 -1 @hirokidaichi 4267 +399 53166
5 0 @poly_soft 3853 +1025 17265
6 +3 @drken 3276 +1242 35489
7 +1 @suin 2633 +577 50141
8 -2 @mizchi 2609 +120 24938
9 -2 @icoxfog417 2580 +154 38828
10 @mpyw 2485 28792
11 0 @rana_kualu 2436 +512 53573
12 +1 @kenmatsu4 2024 +154 15943
13 -3 @dankogai 1915 -16 3300
14 -2 @taguchi 1858 -27 27
15 -1 @yukihiro_matz 1839 -18 119
16 0 @mattn 1717 +63 6545
17 -2 @supermomonga 1704 -50 839
18 -1 @youwht 1650 +187 21283
19 -1 @kazukichi 1464 +73 11191
20 -1 @Qiita 1350 +82 13152

@Yametaro さんが2千人以上のウォッチャーを稼いで一気にトップに躍り出ました。
こちらでも新登場している @mpyw さんは例によって集計漏れだと思われます。

記事も Contributionも全くないのにランクインしている @taguchi さんって何なのって思っていたのですが、ドットインストールの中の人だからみたいですね。

記事分析

残念ながら総記事数の変遷などの集計はできませんでした。

記事LGTM数ランキング

Qiita全体の記事のLGTM数ランキングです。

ランク 前年比 LGTM 前年比 記事
1 0 10642 +1869 Markdown記法 チートシート
2 0 8622 +446 ロシアの天才ハッカーによる【新人エンジニアサバイバルガイド】
3 +1 8545 +1901 プログラミングでよく使う英単語のまとめ【随時更新】
4 -1 8049 +816 ペアプログラミングして気がついた新人プログラマの成長を阻害する悪習
5 +1 6697 +647 うまくメソッド名を付けるための参考情報
6 -1 6538 +132 非デザイナーエンジニアが一人でWebサービスを作るときに便利なツール32選
7 +9 6079 +2038 一番分かりやすい OAuth の説明
8 -1 6021 +386 【まとめ】これ知らないプログラマって損してんなって思う汎用的なツール 100超
9 +1 5391 +561 イマドキのJavaScriptの書き方2018
10 +24 5349 +1887 AtCoder に登録したら次にやること ~ これだけ解けば十分闘える!過去問精選 10 問 ~
11 -2 5245 +386 新人プログラマに知っておいてもらいたい人類がオブジェクト指向を手に入れるまでの軌跡
12 -4 5171 +60 数学を避けてきた社会人プログラマが機械学習の勉強を始める際の最短経路
13 +7 5131 +1251 VSCodeのオススメ拡張機能 24 選 (とTipsをいくつか)
14 0 4833 +604 オブジェクト指向と10年戦ってわかったこと
15 -4 4808 +45 もう保守されない画面遷移図は嫌なので、UI Flow図を簡単にマークダウンぽく書くエディタ作った
16 +7 4637 +773 開設後3週間で収益10万円を得た個人開発サイトでやったことの全部を公開する
17 +1 4563 +610 Chrome拡張の高速な英語辞書ツールをつくりました(Mouse Dictionary)
18 +3 4553 +682 エンジニアの情報収集法まとめ
19 +3 4553 +684 2018年の最先端バックエンドエンジニアに必要なスキルについて考えてみました。
20 +6 4454 +746 質問は恥ではないし役に立つ
21 -9 4365 +3 インフラエンジニアとしてよく使うコマンド集
22 -9 4311 +64 初心者向け、「上手い」シェルスクリプトの書き方メモ
23 +1 4295 +496 Gitのコミットメッセージの書き方
24 -7 4273 +258 Reactを使うとなぜjQueryが要らなくなるのか
25 -10 4183 +91 何かのときにすっと出したい、プログラミングに関する法則・原則一覧
26 4095 Google社のテクニカルライティングの基礎教育資料がとても良かったので紹介したい
27 +11 4092 +857 【図解】Dockerの全体像を理解する -前編-
28 +21 3986 +1077 いまさらだけどDockerに入門したので分かりやすくまとめてみた
29 -4 3978 +196 Pythonを書き始める前に見るべきTips
30 -11 3972 +87 エンジニアなら知っておきたい、絵で見てわかるセキュア通信の基本
31 -2 3926 +258 インフラエンジニアじゃなくても押さえておきたいSSHの基礎知識
32 3916 要件定義~システム設計ができる人材になれる記事
33 3905 良いコードの書き方
34 -2 3845 +324 GitHubで使われている実用英語コメント集
35 -4 3841 +304 「AWS is 何」を3行でまとめてみるよ
36 +7 3823 +706 使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」
37 -7 3794 +237 Vim幼稚園からVim小学校へ
38 -10 3788 +106 ウェブカツ運営者が語る!エンジニアで稼ぐために大切な20のコト
39 -3 3787 +387 AWSアカウントを取得したら速攻でやっておくべき初期設定まとめ
40 +2 3755 +634 個人でも使える!おすすめAPI一覧
41 -2 3755 +573 Go言語の初心者が見ると幸せになれる場所 #golang
42 3717 エンジニアの劣等感との付き合い方
43 -16 3659 -47 ネイティブと働いて分かった英語コミットメッセージの頻出動詞10つ
44 3612 プロジェクトリーダーというお仕事
45 0 3592 +513 すべての新米フロントエンドエンジニアに読んでほしい50の資料
46 -2 3469 +358 [初心者向け] RubyやRailsでリファクタリングに使えそうなイディオムとか便利メソッドとか
47 -12 3466 +54 コードを書く際の指針として見返すサイトまとめ
48 3379 メンバーに恨まれそうな3つのコードレビュー施策を徹底したら、逆にメンバーが爆速で成長した話
49 +23 3378 +894 2020年のフロントエンドマスターになりたければこの9プロジェクトを作れ
50 -9 3369 +236 モデルやメソッドに名前を付けるときは英語の品詞に気をつけよう
51 +10 3307 +586 不思議の国のSE用語
52 -15 3259 -24 特にプログラマーでもデータサイエンティストでもないけど、Tensorflowを1ヶ月触ったので超分かりやすく解説
53 -1 3219 +358 プログラミング勉強を加速させる7つの習慣
54 +31 3213 +860 Markdown記法 サンプル集
55 3205 ls よりも exa を使おう!モダンな Linux コマンド達を紹介
56 -10 3186 +110 VagrantとDockerについて名前しか知らなかったので試した
57 -10 3154 +173 画像処理の数式を見て石になった時のための、金の針
58 -18 3151 -19 2016年 独りで新規WEBサービスを開発・運用した際の知見
59 +20 3142 +727 (下準備編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで
60 -12 3140 +168 JavaScriptを読んでて「なにこれ!?」と思うけれど調べられない記法8選。
61 -11 3097 +221 トップデベロッパーになるために作成したいアプリ8選
62 +16 3074 +654 いまさらだけどGitを基本から分かりやすくまとめてみた
63 -4 2945 +205 個人的に超絶為になったので新人エンジニアに勧めたい記事まとめ
64 -13 2940 +69 脱初心者を目指すなら知っておきたい便利なVimコマンド25選 (Vimmerレベル診断付き)
65 -10 2939 +153 新人プログラマに正月休み中を使って読んでみてほしい技術書をセレクトしてみた。
66 +4 2938 +441 初心者歓迎!手と目で覚える正規表現入門・その1「さまざまな形式の電話番号を検索しよう」
67 -14 2931 +122 不安とストレスから解放される見積りとスケジュール方法
68 -3 2920 +247 WebAPIでエラーをどう表現すべき?15のサービスを調査してみた
69 -13 2896 +129 ゼロからDeepまで学ぶ強化学習
70 -7 2846 +141 新人プログラマに知ってもらいたいメソッドを読みやすく維持するいくつかの原則
71 -14 2825 +65 2017年のフロントエンドエンジニアならこの程度は知ってて当然だよな?
72 -18 2806 +15 プログラマが独立・起業する時によくするミスと対策 まとめ
73 -15 2786 +38 Linux開発環境の基礎知識
74 2785 1時間で出来るWordPress環境構築(※永久無料・・・だった)【※2020/7/1より約300円/月が有料になります】
75 2753 Kaggleに登録したら次にやること ~ これだけやれば十分闘える!Titanicの先へ行く入門 10 Kernel ~
76 2751 【全部無料】ハマると時間が秒で過ぎる英語圏のプログラミング系サイトまとめ【英語学習】
77 -8 2733 +224 なぜ仮想DOMという概念が俺達の魂を震えさせるのか
78 -16 2727 +17 究極のIT系最新技術情報収集用Slackチーム公開 - モヒカンSlack -
79 -15 2726 +37 新卒からの質問をソシャゲっぽい仕組みにしたら捗った話
80 -14 2698 +88 プログラミングで一番難しいのは「見積もり」だと思う
81 -21 2689 -37 英語コミットコメントに使えるオシャレフレーズ集
82 -15 2646 +63 コーディングをするときに鼻血がでるほど便利なwebツールリスト
83 -15 2634 +61 30分で出来る、JavaScript (Electron) でデスクトップアプリを作って配布するまで
84 -13 2610 +120 クラスの命名のアンチパターン
85 2573 新規Webサービスを独りで開発・運用する際に立ちはだかった壁とそれを乗り越えた方法まとめ【個人開発】
86 2565 数時間で完全理解!わりとゴツいKubernetesハンズオン!!
87 2531 エンジニアなら知っておきたい生産性を爆上げするツール8選
88 +7 2497 +279 iPhone/iPad/Apple Watch解像度(画面サイズ)早見表
89 -2 2490 +177 プログラマーの君! 騙されるな! シェルスクリプトはそう書いちゃ駄目だ!! という話
90 2481 スナック「jQuery」
91 -17 2480 +29 Electronでアプリケーションを作ってみよう
92 +4 2477 +259 【今日からできる】コミットメッセージに 「プレフィックス」 をつけるだけで、開発効率が上がった話
93 -10 2465 +81 さよなら本番サーバー
94 -12 2440 +44 [ver 1.2] Git でよく使われるコマンドにイラストによる説明を加えて1枚のチートシートにまとめてみた
95 2438 君には1時間でGitについて知ってもらう(with VSCode)
96 -21 2424 -7 日本の行政機関等が公開しているAPIについてのまとめ(2016年8月17日暫定版。随時更新)
97 -21 2415 -14 英語のコメントや issue で頻出する略語の意味 (FYI, AFAIK, ...)
98 -21 2414 -9 httpsだからというだけで安全?調べたら怖くなってきたSSLの話!?
99 -11 2397 +129 エンジニアは全員技術記事を書くことを習慣化した方がいいぞ
100 -16 2389 +20 Android開発を受注したからKotlinをガッツリ使ってみたら最高だった

Markdown記法 チートシートがついに5桁の大台に乗りました。
まあ、Qiitaで何かやろうとしたらとりあえず最初に参照する記事ですからね。
これからもQiitaの人口が増えるたびにLGTM数が増えることでしょう。

新規ランクインは15記事です。

ランク LGTM数 記事
26 4095 Google社のテクニカルライティングの基礎教育資料がとても良かったので紹介したい
32 3916 要件定義~システム設計ができる人材になれる記事
33 3905 良いコードの書き方
42 3717 エンジニアの劣等感との付き合い方
44 3612 プロジェクトリーダーというお仕事
48 3379 メンバーに恨まれそうな3つのコードレビュー施策を徹底したら、逆にメンバーが爆速で成長した話
55 3205 ls よりも exa を使おう!モダンな Linux コマンド達を紹介
74 2785 1時間で出来るWordPress環境構築(※永久無料・・・だった)【※2020/7/1より約300円/月が有料になります】
75 2753 Kaggleに登録したら次にやること ~ これだけやれば十分闘える!Titanicの先へ行く入門 10 Kernel ~
76 2751 【全部無料】ハマると時間が秒で過ぎる英語圏のプログラミング系サイトまとめ【英語学習】
85 2573 新規Webサービスを独りで開発・運用する際に立ちはだかった壁とそれを乗り越えた方法まとめ【個人開発】
86 2565 数時間で完全理解!わりとゴツいKubernetesハンズオン!!
87 2531 エンジニアなら知っておきたい生産性を爆上げするツール8選
90 2481 スナック「jQuery」
95 2438 君には1時間でGitについて知ってもらう(with VSCode)

Google社のテクニカルライティングの基礎教育資料がとても良かったので紹介したいが4000票以上を獲得しました。
エンジニアはコーディング力だけではなく日本語力(英語力でもいいけど)も大事ですからね。

2019年の新着は26記事、2018年は23記事だったので、今年はだいぶ減少しました。
100位でも2400LGTMが必要ですから、今後もハードルが上がっていくのは避けられないでしょう。

そもそも、まずジャンル選びの時点で相当数が脱落してしまいますからね。
専門性が高い記事ほど、どれだけ優れていようともLGTM数はどうしても控えめになります。
そういった隠れた良い記事を掘り出そうという研究もあるにはありますが、なかなか難しいところですね。

Organization分析

最後にOrganization分析です。

Organizationは一覧が残っているので、ここからデータをぶっこ抜いてくることができました。
つまり(ミスがなければ)完全なランキングです。

全体

Organization総数は、べつに集計とかしなくても一覧の最終ページを見ればいいんですよ。

最終65ページ目に14組織だったので、64*20+14= 1294 です。

昨年は958だったようなので、336組織が増えました。
増加数は昨年とほぼ同じで、順当に成長しているようです。

Organization別LGTMランキング

まずは組織ごとのLGTM数ランキングです。

ランク 前年比 名前 LGTM数 前年比 記事数 メンバー数
1 +5 @admin-guild 112708 +52695 2865 182
2 0 @tis 103777 +34154 1604 91
3 0 @yumemi 96609 +27251 2141 128
4 -3 @mercari 93783 -16222 1617 83
5 -1 @yyphp 87430 +23799 2529 23
6 -1 @sonicgarden 73336 +11093 625 18
7 @engineerlife 70979 2349 70
8 -1 @dena_coltd 65362 +12352 1464 116
9 @craftsman_software 53644 1480 6
10 -2 @rector 53183 +4171 45 3
11 -1 @shouldbee 52720 +11222 1439 3
12 @dmmcom 52643 1190 71
13 -1 @nri 43459 +8904 526 60
14 -5 @cyberagent 41190 -5700 857 60
15 -2 @future 41115 +6658 914 95
16 -2 @zozotech 40423 +7813 1568 146
17 -2 @iotlt 39328 +8333 3054 128
18 +6 @ntt-data-msi 38399 +13679 101 5
19 -8 @wantedly 37955 +2093 486 29
20 -4 @crowdworks 34108 +3291 388 34
21 +1 @unity-game-dev-guild 32702 +7011 1387 57
22 -5 @yahoo-japan-corp 32692 +2323 923 73
23 -3 @dwango 32519 +6557 793 72
24 -5 @lifull 31682 +4870 1193 100
25 @phper-oop 29343 547 12
26 -8 @plaid 29259 +1685 500 36
27 @m3dev 28303 707 43
28 -3 @synapse 27709 +3392 312 2
29 -1 @jrits 26288 +3962 983 45
30 @qiitadon 26111 1752 44

1位になったのは、LGTM数記事数メンバ数すべてを圧倒的に増やした@admin-guildです。
他にも5位の@yyphp、初登場7位の@engineerlifeなどは企業ではなくコミュニティです。
従って会社・学生にかかわらず自由参加・複数参加することができるのでLGTM数も増やしやすいという有利な点があります。

そんな中でも企業単位で健闘している2位@tis、3位@yumemi、6位@sonicgardenなどは流石ですね。

上位陣で総LGTM数が減少した組織は4位@mercariと14位@cyberagentでした。
特に@mercariは昨年1位から大きくLGTM数を落としています。

初登場9位の@craftsman_software@suin さんの参加、初登場12位の@dmmcom@mpyw さんの参加によるものだと思われます。
個人上位層の加入によってわりと大きく変動しますね。

Organization記事数ランキング

組織単位での記事数ランキングです。

ランク 前年比 名前 記事数 前年比 LGTM数 平均LGTM
1 0 @iotlt 3054 +893 39328 12.88
2 +3 @admin-guild 2865 +1407 112708 39.34
3 -1 @yyphp 2529 +387 87430 34.57
4 @engineerlife 2349 70979 30.22
5 -2 @yumemi 2141 +203 96609 45.12
6 @qiitadon 1752 26111 14.90
7 -3 @mercari 1617 -210 93783 58.00
8 0 @tis 1604 +508 103777 64.70
9 0 @zozotech 1568 +478 40423 25.78
10 @craftsman_software 1480 53644 36.25

こちらも@admin-guildの増加が圧倒的で、首位@iotltの首元まで迫ってきました。
4位@engineerlife、6位@qiitadonなど、こちらもやはりコミュニティ組織の躍進が大きいですね。

Organizationメンバ数ランキング

単純にメンバ数のランキングです。

ランク 前年比 名前 メンバ数 前年比 LGTM数 1人あたりLGTM
1 +6 @admin-guild 182 +94 112708 619.27
2 +1 @zozotech 146 +35 40423 276.87
3 -1 @yumemi 128 +7 96609 754.76
3 -2 @iotlt 128 +3 39328 307.25
5 -1 @dena_coltd 116 +17 65362 563.47
6 0 @lifull 100 +9 31682 316.82
7 +1 @future 95 +8 41115 432.79
8 +1 @tis 91 +10 103777 1140.41
9 -4 @mercari 83 -15 93783 1129.92
10 0 @yahoo-japan-corp 73 -3 32692 447.84

メンバ数は誰でも参加できるコミュニティが有利なはずですが、その中でもしっかり多くの開発者が情報発信している@zozotech@yumemiは流石です。

しかし@mercariは何か大量リストラでもあったんですかね。

Organization1人あたりLGTM数ランキング

最後は1人あたりのLGTM数ランキングです。

ランク 名前 一人あたりLGTM LGTM数 メンバ数
1 @rector 17727.67 53183 3
2 @shouldbee 17573.33 52720 3
3 @synapse 13854.5 27709 2
4 @craftsman_software 8940.67 53644 6
5 @pugiemonn_com 8850 8850 1
6 @meson 8383.5 16767 2
7 @ntt-data-msi 7679.8 38399 5
8 @arow-oss 7379 7379 1
9 @consensus-base 6074 12148 2
10 @sirok 4995 9990 2

少人数組織は@rector@hirokidaichi さん一人で、@shouldbee@suin さん一人で稼いでるみたいに個人力に大きく依存してしまうので、偏ったランキングになってしまいます。
極端な話、私が一人組織を作れば断トツトップに躍り出られますからね。
やりませんけど。

ということで20人以上の組織に絞ったランキングが以下です。

ランク 名前 一人あたりLGTM LGTM数 メンバ数
1 @yyphp 3801.3 87430 23
2 @wantedly 1308.79 37955 29
3 @tis 1140.41 103777 91
4 @mercari 1129.92 93783 83
5 @sakura_internet 1107.32 24361 22
6 @engineerlife 1013.99 70979 70
7 @crowdworks 1003.18 34108 34
8 @plaid 812.75 29259 36
9 @repro 766.17 22985 30
10 @iwate-pu 762.22 20580 27

一部参加者だけではなく、構成員の多くがきちんと記事を書いているということなので、組織全体でのモチベーションの高さが窺えますね。

おわりに

graphQLめんどいのでRESTも用意してほしい。

Qiita APIがわりと役に立たなかったため、ユーザページや記事を気合いでスクレイピングする羽目になりました。
まあ、Qiita APIは各ユーザが自分の情報に関して使うものであって、全ユーザをどうこうするために作られたものではないから当たり前ですが。

ランキングの上位記事、上位ユーザというのは何れもそれなりに理由があってその位置にいるものなので、関係のない分野だからと見ていなかった記事やユーザについても、試しに覗いてみるのも面白いかもしれません。
新たな知見や興味が産まれるかもしれませんよ。
ちなみに個人的に調査中に目を通した中で一番笑った記事はこれでした。

自分が見たかったから始めたのですが、とても大変だったので来年はたぶんやりません。
最後に、昨年までこんな面倒くさいことを毎年やってくださっていた @t_nakayama0714 氏に感謝を。

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