20191127のPHPに関する記事は16件です。

WSLのUbuntu環境でPC内音楽データをWeb操作する(おまけでyoutube音楽とGooglehomeで伝言)

はじめに

●PC内音楽データをWEBで操作し、PCスピーカで再生できるようにする。
(Googlehomeで声で操作するのWeb操作版です。声でキーワードがうまく入力できない場合に使用してます)
【操作例】WEBから「竹内まりや」と入力する
コメント 2019-11-27 230824.png
●おまけ
youtube音楽:下記の記事と同じです。
 WSLのUbuntu環境でyoutube音楽をWeb操作する(おまけでradikoとサイマルラジオ)
伝言:Googlehomeで伝言を再生します。google-home-notifierを使用。

環境

●Windows10 HOMEのPCにWSLのubuntuをインストールする。
●ubuntuでapache2,npm,node.js,youtube-dl,mplayerをインストールする
●WSLのubuntuでpulseaudioでPCのスピーカを使うようにする
●Windows側でpulseaudioサーバのインストールが必要です
 https://www.cendio.com/thinlinc/download の 「Client Bundle」のリンクからダウンロードできます

PC内音楽データを再生するプログラム(pcplay.js)

●単体で起動する方法
$node pcplay.js 検索キー(例 竹内まりや)

const exec   = require('child_process').exec;

var limit = 1;
var items;
var item;
var title;
var id;

//値取得
const value = process.argv[2];
if (!value) return
console.log(value)

// キーワードから検索し、音楽データのパスを取得する。
play_pcmusic(value);
// 音楽ファイルのパスを取得し、再生する。
function play_pcmusic(keyword) {
  command = 'cat /mnt/j/music/htdocs/music/list.txt | grep "'  + keyword + '"';
  var exec = require('child_process').exec;
  exec(command, {maxBuffer: 40000*1024}, 
function(error, stdout, stderr) {
    if (error !== null) {
      command = 'curl -X POST -d "text=指定された曲はありません" http://192.168.1.82:8080/google-home-notifier'
      exec(command, {maxBuffer: 40000*1024}, function(error, stdout, stderr) {
        if (error !== null) {
          console.log('Exec error: ' + error);
        }
      });
    } else {
      console.log(stdout);
    }
 });
  command = 'cat /mnt/j/music/htdocs/music/list.txt | grep "'  + keyword + '">/mnt/j/music/htdocs/music/playlist';
  console.log(command)
  var exec = require('child_process').exec;
  exec(command, {maxBuffer: 40000*1024}, 
function(error, stdout, stderr) {
    if (error !== null) {
      console.log('Exec error: ' + error);
    }
  });
  command = 'mplayer -shuffle -playlist /mnt/j/music/htdocs/music/playlist';
  console.log(command)
  var exec = require('child_process').exec;
  exec(command, {maxBuffer: 40000*1024}, 
function(error, stdout, stderr) {
    if (error !== null) {
      console.log('Exec error: ' + error);
    }
  });
}

index.php

<?php
if(isset($_GET['comment1'])){
$comment = $_GET['comment1'];
exec("killall mplayer");
exec("node /home/ユーザ名/ytplay.js " .$comment);
}
if(isset($_GET['comment2'])){
$comment = $_GET['comment2'];
exec("killall mplayer");
exec("node /home/ユーザ名/pcplay.js " .$comment);
}
if(isset($_GET['comment3'])){
$comment = $_GET['comment3'];
exec("killall mplayer");
exec("curl -X POST -d 'text=".$comment."' http://192.168.1.82:8080/google-home-notifier");
}
if(isset($_GET['id'])){
$id = $_GET['id'];
if($id=="stop"){
exec("killall mplayer");
}
}
?>
<html>
<head>
<meta name="viewport" content="width=device-width">
</head>
<body>
<p><a href="index.php?id=stop">stop</a></p>
<form action="index.php" method="get">
<input type="text" name=comment1>
<input type="submit" value="youtube">
</form>
<form action="index.php" method="get">
<input type="text" name=comment2>
<input type="submit" value="PC音楽">
</form>
<form action="index.php" method="get">
<input type="text" name=comment3>
<input type="submit" value="伝言">
</form>
</body>
</html>

まとめ

●お気に入りのPCスピーカでPC内の音楽データを再生します
●プログラムはラズパイでも同様に動作しますが、youtube-dlの動作が遅く、再生開始に少々時間がかかります。

参考

WSLのUbuntuでyoutube音楽をGoogleHomeで操作する
WSLのUbuntuでPC内の音楽データをGoogleHomeで操作する
WSLのUbuntu環境でyoutube音楽をWeb操作する

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

WordPressを利用したハンズオン形式のAWS学習書籍 HTTP 500エラーでWelcomeページが見られない

結論:PHPのバージョンアップが必要だった

以下、全てWebサーバーとして利用する想定のAWS EC2内でのコマンド。
書籍内の手順通りにPHPのインストールをした場合はまず既存PHP及びモジュール削除。

#利用中のモジュールを確認
$ yum list installed | grep php
php.x86_64                            5.4.16-45.el7                    @base
php-cli.x86_64                        5.4.16-45.el7                    @base
php-common.x86_64                     5.4.16-45.el7                    @base

#消去
$ sudo yum erase -y php-common php-cli php

#upgrade
$ sudo yum upgrade

Remi’s RPM repository追加して、PHP71とモジュールをインストール

特に「php71-php」をインストールしないと、ApacheがPHPを読んでくれなかったのでハマった。

#これをしないとRemi’s RPM repositoryがインストールできない
$ sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

#Remi’s RPM repositoryのインストール
$ sudo yum install -y https://rpms.remirepo.net/enterprise/remi-release-7.rpm

#PHP71及び(書籍指定の)必要なモジュールをインストール
$ sudo yum install -y php71 php71-php php71-php-cli php71-php-common

#Apache再起動
$ systemctl restart httpd

書籍内で必要とされているモジュール(旧PHP)で、PHP71対応モジュールについては要Google先生。
これでWordPressのウェルカムページを見ることができるはず。
あまり覚えてないけど体感3日はハマった。

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

Moodle 3.7 マニュアル - Red Hat Enterprise Linux へのインストール

原文

Red Hat Enterprise Linux へのインストール

Note: This document is about installing Moodle 3.7 in an RedHat Enterprise Linux (RHEL) 8

Contents

1 サーバのインストール
2 ネットワークインターフェース
3 ホスト名とドメイン名を設定する
4 システムの登録
5 SELinux
6 ファイアウォール
7 MariaDB / MySQL
8 Moodle のセットアップ
8.1 ダウンロード
8.2 解凍しファイル権限その他を設定する
8.3 config.php を設定する
9 Apache
9.1 ドキュメント・ルートを設定する
10 PHP
11 Moodle のインストール
12 cron job のセットアップ
12.1 CLI バージョン
12.2 Web バージョン
13 あなたの新しいインストール(環境)を試す
14 SSL 証明書をインストールする
15 関連項目 See also

1 サーバのインストール

  • Web Server Moodle 3.7 needs PHP 7.1; RHEL8 comes with PHP 7.2.[1]
  • Database Moodle 3.7 needs MariaDB 5.5 or MySQL 5.6; RHEL8 comes with MariaDB 10.3 and MySQL 8.0 (They cannot be installed at the same time).[2]
  • BEWARE OF the 'Server with a GUI' option, it may not work as expected.

Note: Set up the firewall if necessary. You probably only need to enable HTTP/HTTPS (and perhaps FTP and SSH) access to your server machine, unless you know the difference.

2 ネットワークインターフェース

During installation, under "System" -> "Network & Host Name", remember to enable the NIC. It's not enabled by default.

3 ホスト名とドメイン名を設定する

Type system-config-network to open the GUI editor. Click on the DNS tab. In the "DNS Search Path" fill in your domain name for example myuniversity.edu. Now ensure the "Hostname" contains the computer name you will use and click activate to make changes

4 システムの登録

  • To receive package updates, create a user account at redhat.com, and then login and register as developer at https://developers.redhat.com/
  • Subscribe the system by:

subscription-manager register --auto-attach

Enter the username and password as requested.

  • Update the system and then reboot
yum update
reboot

See [3]

5 SELinux

Default RedHat Enterprise Linux comes with SELinux set to 'enforcing'. But this may cause user problem accessing web content placed at directory other than the default directory (/var/www/html) or other access problem. If you are not used to SELinux and setting permissions, it's (maybe less secure but) often easier to lower the SELinux level to 'permissive' or even 'disabled'.

# vi /etc/sysconfig/selinux

SELINUX=disabled

See the CentOS [4]

6 ファイアウォール

The internal firewall (RHEL since version 7 uses 'firewalld'[5]) is on by default. It will block the access to the web server. You may stop it first to test connection:

service firewalld stop

and then either disable it:

chkconfig firewalld off

or enable permanent HTTP access to it, you may want to enable HTTPS as well:

firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https

Restart the firewall and then check the allow status:

service firewalld restart
firewall-cmd --zone=public --list-services

To use iptables instead of firewalld, see [6]

7 MariaDB / MySQL

  • Make sure at least 'mariadb' and 'mariadb-server' packages are installed. (use "mysql" and "mysql-server" for MySQL)
yum install mariadb mariadb-server
  • Then get the daemon running, it is not running by default. And set it to auto-start. See also 7
service mariadb start; chkconfig mariadb on
  • Edit /etc/my.cnf (May be different for MySQL) (MariaDB 10.3 doesn't need this as these are already the default settings.)
vi /etc/my.cnf

Scroll down to the [mysqld] section and under "Basic Settings", add the following line under the last statement.

innodb_file_format = Barracuda
innodb_file_per_table = 1
innodb_large_prefix
  • If you haven't yet, as root, change the MariaDB/MySQL root password, also secure the installation mysql_secure_installation
  • Next, set up the MariaDB/MySQL database (see http://moodle.org/doc/?file=install.html#Database for more details)
  • Launch MariaDB/MySQL as root mysql -u root -p (at the password prompt, enter the password from above)
  • At the '>' MariaDB/MySQL prompt, enter the following commands (MariaDB/MySQL commands are ended with a ';') CREATE DATABASE mymoodle CHARSET 'utf8mb4'; ('mymoodle' is the name of the database you would like to use, it will be entered to the Moodle 'config.php' later) GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,CREATE TEMPORARY TABLES,DROP,INDEX,ALTER ON mymoodle.* TO moodleuser@localhost IDENTIFIED BY 'moodlepass'; (as above, 'mymoodle', 'moodleuser' and 'moodlepass' will be entered to the Moodle 'config.php' later) flush privileges; quit
  • (! Consider MariaDB/MySQL security - not covered here. If you run a firewall, you don't have too much to worry about.)

8 Moodle のセットアップ

(I will install under /usr/moodle, data in /usr/moodle_data)

8.1 ダウンロード

  • Download your favourite version of Moodle from moodle.org (.zip archive is easiest) as Root create folder under /usr and copy zip su mkdir /usr/moodle mkdir /usr/moodle_data cp moodle_111.zip /usr/moodle
  • If you prefer you can install the GIT version directly for all the latest features. Instead of downloading and copying the zip file. See Git_for_Administrators for details. cd /usr git clone git://git.moodle.org/moodle.git
  • Or if you prefer you can install the CVS version directly for all the latest features. Instead of downloading and copying the zip file. cd /usr/moodle cvs -d:pserver:anonymous@uk.cvs.moodle.org:/cvsroot/moodle login cvs -z3 -d:pserver:anonymous@uk.cvs.moodle.org:/cvsroot/moodle co moodle

8.2 解凍しファイル権限その他を設定する

  • Still as root we unpack moodle and rename to something appropiate (I have multiple moodle installs, hence this setup). I will call this install mymoodle. cd /usr/moodle unzip moodle_xxx.zip mv moodle mymoodle (optional step - I have more than one install under /usr/moodle) mkdir /usr/moodle_data/mymoodle (same name as the moodle install above) chown -R apache:apache /usr/moodle (! Giving Apache full rights to your Moodle programs is not secure. Check out the forums for recomendations on how to secure a production environment.) chown -R apache:apache /usr/moodle_data

8.3 config.php を設定する

  • Still as root copy and edit the config file, you should know the host/domain name for your server cd /usr/moodle/mymoodle cp config-dist.php config.php vi config.php (or whatever your favourite editor is!)
  • Your config.php settings should be something like... dbtype = 'mariadb' (use 'mysqli' for MySQL) dbhost = 'localhost' dbname = 'mymoodle' dbuser = 'moodleuser' dbpass = 'moodlepass' (<-- better make this something of your own) prefix = 'mdl_' (Use different prefix if there is more than one instance of Moodle on the same server, and you plan to share the database) wwwroot = 'http://myhost.mydomain' (If you only want to try moodle out and will not be accessing it from other machines you can use 'http://localhost/mymoodle') dataroot = '/usr/moodle_data/mymoodle'
  • Save your changes and exit from the editor

9 Apache

  • Install it if it's not installed already.
yum install httpd

or everything

yum install httpd*
  • Start it and make it auto-start after reboot:
service httpd start; chkconfig httpd on
  • Open a web browser and make sure you can connect to the installed web server and default port (80) of the server. If not OK, it may be blocked by the firewall (see above). Correct the problem before continuing.
  • Edit the Apache configuration file

    /etc/httpd/conf/httpd.conf

  • Right at the end of the file add the following lines:
    (the directory used during Moodle installation)
    DirectoryIndex index.php
    AcceptPathInfo on
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all

    Alias /mymoodle "/usr/moodle/mymoodle"

  • Don't insert a space in "allow,deny" (common mistake!)

  • You might also want to run through the rest of the config file and make some other (obvious) changes - administrator email and suchlike. Not vital though.

  • Run the Services application (same as for Mysql) - tick and start "httpd", then save changes and exit.

9.1 ドキュメント・ルートを設定する

Edit

/etc/httpd/conf/httpd.conf

Change From: DocumentRoot /var/www/html

Change To: DocumentRoot /var/www/html/mymoodle

If you want the web site to be served as "http://www.whatever.com/mymoodle" instead of "http://www.whatever.com", don't change it, and modify the 'wwwroot' parameter of Moodle 'config.php' file accordingly.

10 PHP

  • Install PHP:
yum install php php-cli php-common php-fpm php-gd php-intl php-json php-mbstring php-mysqlnd php-opcache php-pdo php-xml php-xmlrpc php-pecl-zip php-soap
  • Check the installed PHP version:
# php -v
  • Restart the web server so that PHP can start working:
service httpd restart
  • Create a "phpinfo.php" file within the "/var/www/html" directory (or anywhere the Apache "DocumentRoot" points to) with the following content:
<?php
phpinfo();
?>

And then open web browser and browse to "http://webserver/phpinfo.php" to make sure PHP is working with the web server. Then remove the file for security reason.

11 Moodle のインストール

Now everything's ready. Use web browser to open "http://webserver/mymoodle/install.php" to start the installation.

12 cron job のセットアップ

As root user edit the /etc/crontab file using vi (or another editor) OR you can add a line to the root user's "personal" crontab (don't do both!).

12.1 CLI バージョン

Note: According to Moodle's documentation, users should use the CLI version if possible, as the web version may be removed in future.[8]

  • If you wish to place an entry in your root user's crontab use:
crontab -e

Add the following line:

 */5 * * * * /usr/bin/php /path/to/mymoodle/admin/cli/cron.php

to run the command every 5 minutes.

12.2 Web バージョン

Note: Use the CLI version if possible.

  • If you wish to place an entry in your root user's crontab use:
crontab -e

Add the following line:

*/5 * * * * /usr/bin/wget -O /dev/null http://localhost/mymoodle/admin/cron.php
                (change the URL as appropriate for your site)

  • If you wish to add an entry in /etc/crontab: Open the /etc/crontab file in an editor (vi). Add the following line:
*/5 * * * * root /usr/bin/wget -O /dev/null http://localhost/mymoodle/admin/cron.php
            (change the URL as appropriate for your site)

In either case, don't forget to save the file and exit (in vi that is <Esc>, then ':wq')

13 あなたの新しいインストール(環境)を試す

http://myhost.mydomain/admin or http://myhost.mydomain/mymoodle/admin

or, if you are running the browser on the same machine

http://localhost/admin or http://localhost/mymoodle/admin

14 SSL 証明書をインストールする

After installing the SSL certificate, change the 'http' to 'https' in the 'wwwroot' parameter of Moodle 'config.php' file.

15 関連項目

Unix or Linux Installation
Installing Moodle

カテゴリ:Administrator (翻訳準備中)インストール

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

東大の学園祭のウェブサイト部門の技術がPHPからNuxtになるまで

前書き

この記事は、純粋に技術を紹介するというよりは、「いかに技術を浸透させたか」「つらみにどう対処したか」という「メタ技術」的な話になります。そのため、要素要素の技術の詳細には立ち入りません。ご了承ください。

また、長々と書いていますが、まとめだけ見たい人は一番したの「まとめ」までスクロールしてください。

対象読者

  • これから情報システム部門を立ち上げようとしている人
  • 情報システム部門にいて、新しく技術を導入したいけれど、技術的な「負の遺産」に悩んでいる人
  • 人の入れ替わりが激しく、継続的な技術の蓄積が難しいと感じている人
  • 情報システム部門にいるけど、他の部署からの圧力による要件追加などに悩んでいる人

なぜ「学園祭」なのか

大学の学園祭の運営をしている、と聞くと、皆さんはどんなことを思い浮かべますか?
学園祭の楽しい記憶などがあっても、運営、と聞くと「?」となってしまう人が多いと思います。

今回のアドベントカレンダーは、そんな、普段目につかないようなところで頑張っている大学の学園祭の中でも、さらに一段と見えないところで頑張っている情報部門のアドベントカレンダーです。

ほとんどの企業が自分のウェブサイトを持ち、旅行するときは乗換検索、料理は食べログやGoogle Mapsに当たり前に頼るようになった2019年末の現在でも、情報部門をもつ学園祭運営団体はあまり多くないのが現状です。

経験からすると、それは「学園祭の運営団体でITをやるのはつらい」に起因するように思います。しかし、その学園祭という特殊な環境にありながら、その「つらみ」はIT企業であれば当たり前に遭遇するような普遍的なものばかりです。

  • 人がすぐ辞める
  • スキルの高い人が少ない
  • 他の部署からの圧力がある
  • 謎の秘伝のコードがある

etc...

今回は、そんな「つらみ」といかに折り合いをつけながらITをやっていくのかという問題に対して、「技術選択」でどのように対処したのか。
僕が在籍し、技術選択を行った2017-18年にかけての東京大学の駒場祭/五月祭実行委員会の事例を紹介します。

時系列

〜2016年 PHPの時代

2016年まで、駒場祭ではウェブサイトは基本的にはPHPで作られていました。いつからPHPで作られているのか、そしていつからそのようになっているのか厳密なことは分かりませんが、委員会内部の断片的な記録を辿ると、2000年代の後半には既にそのような形態になっていたことが伺えます。

さて、「PHPで開発」と言ってもいろいろな状況があり得ます。僕が駒場祭委員会に入った大学1年生の時の状況は、基本的には以下のような状況でした。

開発者のスキル・人数

1,2年生合わせて5人程度、ほとんどは大学でプログラミングをはじめた人です。もちろん、委員会でも何もしないわけではなく、入会してしばらくは「講習会」と称して2-3ヶ月ほど研修のようなものがあります。しかし、IT企業でのような集中的なものではなく、1週間に1-2時間程度のもので、さらにはJavaScriptしか基本的には教えないという極めて不十分なものでした。つまり、PHPに関してはほぼ全員が教育もなく先輩のコードを見様見真似したりする程度でした。

技術スタックと技術蓄積の状況

PHP-FPMで書かれていました。ざっくりいうとCGIです。「Perlで掲示板を作ろう!」みたいな本で一通り実装したことのある世代には非常に馴染みの深いものだと思います。

これだけでもかなりレガシーな匂いがしますが、それに加えて、パッケージマネージャーもないという状況でした。つまり、ライブラリを入れたりするのが非常に大変だったわけです。(流石にGitはありました。)

それでも腐っても東大生なので、頑張れば無理やり求める実装が出来上がってしまいます。結果として秘伝のタレのようなコードが多くあり、しかも初心者には読み解けない。メンテナンスができない。という状況でした。

しかも、駒場祭委員会には大学1,2年生しか在籍できないため、それらをリファクタできるレベルの技術に達する人もなかなか現れませんでした。東大は(2年はともかく)1年生の、特に理系のカリキュラムはかなり重いため、必然的にリファクタできるレベルの技術を手にする人はかなり限られていました。

2017年 Node.js(Express & Pug)への移行

PHP→JS

先ほどの状況の問題を整理すると以下のようになります。

  • PHPを書ける人材を育てられていない
  • パッケージマネージャーがない
  • 秘伝のタレコードが多い

一つ目は、そもそも委員会ではPHPを書いているのに、研修ではJavaScriptしか教えていないことに由来する問題です。しかし、実質教えることのリソースを増やしてPHPを教えるというのもとても厳しいものでした。これは、2-3ヶ月以上教えると、今度はウェブサイトを作る時間が取れなくなってしまうからです。
そのため、推定10年弱続いた伝統を断ち切って、フロントエンドをJSだけで実装できるように改めて技術選定を行いました。

具体的にはExpressとPugを採用しています。ビルドはGulpで行っています。
当時もReact,Angular(Vueはまだ日本では比較的普及している途中だったようです)などのフロントエンドフレームワークはかなり有名でしたが、「教えきれない」という理由でウェブサイトでの導入を断念しています。(とはいえ、他のより小規模なシステムには採用しています。)
ExpressもPugも学習コストの少ないフレームワークだったので、移行そのものは比較的楽でした。

二つ目についても、PHPの場合はComposerなどのツールがありますが、Node.jsの場合はnpmでかなり簡単にライブラリをいれることができるようになりました。

三つ目もかなり状況が改善されます。PHP時代のコードのほとんどに対し、対応するライブラリを見つけられたため、そもそも実装が減ったので、秘伝のタレコードなるものも自然と減ります。

秘伝のタレ、再び

一見良いことづくめで、実際最初の1-2ヶ月は良い感じに回っていましたが、結論からいうとExpress & Pugも狼人間に対する銀の弾丸ではありませんでした。

ライブラリの大量投入により実装そのものは大幅に減り、僕らはより難しい、抽象的な問題に集中できるようになりました。しかし、今まではみんながしなければいけなかった「難しい実装」が特定の人に集中する、ということが起こります。集中するだけならこれはこれで良いのですが、問題は、難しい実装をする人が多忙により後世に知見を引き継げないということでした。

具体的には、Expressのgulpのスクリプトがそうなりました。当時の駒場祭委員会では、gulpで「ファイルが保存されたら再ビルド & リロード」などのタスクを定義していました。しかし、かなり複雑な実装だったため、それらを理解できる人がいないという問題が発生しました。

政治的圧力による要件追加

これはコミュニケーションの不足なのですが、Twitterカードなどを表示するためのOGPコードの導入が後付けで決まります。ウェブサイトを実装するのは駒場祭委員会のシステム局の管轄ですが、局長である僕はその要求を断ることができませんでした。これは、ウェブサイトの内容などを決める他の局の方が基本的に発言力が強かったことに由来します。

要件に入ってなかったのを半強制的に入れることになったため、当然、かなりの実装コストを強いられました。これにより、他の実装に回せたはずのリソースを吸われてしまい、スケジュールの遅延などが悪化しました。

2018年 VueとNuxtの導入

先ほども言ったように、駒場祭委員会に在籍できるのは大学の1,2年生だけなので、これからの話は五月祭実行委員会での出来事になります。

秘伝のタレの解消、その2(Nuxt.jsへの移行)

五月祭実行委員会では、今度は1-3年が12-6月にかけて祭りの運営をしています。
その中で2年生として入った僕は今度は、中間学年として改めてウェブサイトの技術選定を行うことになります。

しかし、五月祭でExpress & PugでまたGulpを書き、秘伝のタレを生み出すのも気が引けます。何より、そのGulpスクリプトによる構成はOGPコードの実装が非常に面倒な構成を前提としていたので悩みました。

そんな時に出会ったのがNuxt.jsでした。

2018年の1月当時、Nuxt.jsはv1になったばかりという非常に新しいフレームワークでしたが、ビルドやページ追加などの指針が明確に整理され、ウェブサイトの基本的な構造を非常に簡単に作れるという点で非常に優れていました。これにより、さらに秘伝のタレコードを減らすことができるようになりました。

Vue.jsの導入

Nuxt.jsはVue.jsを前提にしたフレームワークですので、当然チームで使う際にはVue.jsの概念、コンポーネントやディレクティブ、プロパティー渡しなどを普及させる必要があります。

VueはReactなどに比べるとHTML & CSSからの移行は楽なのですが、JS部分の移行に関してはそうは行きません。しかし、これについてもVue.jsの公式ドキュメントが非常に充実していたため、教える側としてはかなり楽でした。

政治的圧力への対処

政治的圧力がしんどい場合の解決策はいろいろありますが、当時の僕が最初にとった手段は「そもそも政治的圧力が発生しないようにどうにかする」というものでした。

つまり、事前に要件は決めつつ、「後からの要件追加は、実装コストによっては却下します。なぜなら他の、より優先度の高い実装の障害になるからです。」という方針でまずは他の担当の合意を取り付けました。
これにより、要件の決定権がなく、勝手に仕事のゴールポストをずらされるという状況がかなり改善します。

その上でもごねてきた連中に対しては合意を盾に容赦無く提案を却下しました。
面白いのは、普通なら信頼されなくなると思うところが、これにより優先度の高い実装に優先的にリソースを回すことができるようになり、結果として信頼関係が強化されたことです。

冷静に考えてみるとこれは当たり前で、能力を超えた仕事を請負っても失敗するのだから、わかっている場合は最初から請けない方が「請負った仕事は終わる」確率は上がります。(いささか力技でしたが)

まとめ

つらいところ

  • 初心者が大量に入ってくる
  • 2年程度しかいないのでスキルの高い人が少ない
  • 秘伝のタレコードがある
  • 政治的圧力をかけられて要件が追加されたりする

どうしたか

  • 初心者でもできる方法を模索する
    • 駒場祭/五月祭委員会の場合は、それがNuxt.jsだった
  • 秘伝のタレコードは思い切って捨てる
    • 学習コストの少ないものを採用すると移りやすい
  • 要件追加の方法を合意し、ごねる人には毅然とした態度で
    • 長期的な信頼関係を築くにはむしろその方がよい
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

「3分で理解するWEBプログラミングセキュリティ 01」 SQLインジェクションとは?

3分で理解するWEBプログラミングセキュリティ 01

3分で理解するWEBプログラミングセキュリティ
↓↓記事が出来次第Link貼って行きます↓↓
No.01 SQLインジェクションとは?
No.02 クロスサイトスクリプティングとは?
No.03 クロスサイトリクエストフォージェリとは?
No.04 ディレクトリトラバーサルとは?

はじめに

プロかそうでないかの差とも言うべきでしょうか、未経験者と実務経験者の最大の差はセキュリテイに関しての意識だと思っております。
システムを作ることも大事ですが、守ることの方が大事です。
未経験者のポートフォリオにも最低限組み込んでおきたいセキュリティを簡単に紹介していきます。

1.SQLインジェクションとは?
・概要
・具体例
2.SQLインジェクション対策(PHPでの実装例)
・文字エンコーディングを指定する
・プレースホルダで実装する

1.SQLインジェクションとは?

概要
 一般的に、入力フォームで入力した内容をSQL文に埋め込んで命令文を作成し、DB操作を行います。
 この時、悪意のあるデータを入力し、DBを改ざんや削除したり、攻撃することをSQLインジェクションと言います。

具体例
ソースに以下のコードが書かれていたとします。

qiita.rb
SELECT USER_ID,PASSWORD FROM USER_TBL WHERE USER_ID = $userid

$useridの所に入力した内容が入ってくるのですが、入力フォームに、以下のデータを入力したとします。

qiita.rb
20 or 1=1'

or ’1’=’1'はUSER_IDの値に関係なく、検索条件がtrueとして成立してしまい、USER_IDが常に返ってくる構文になるため、全てのUSER_IDとPASSWORDを取得できてしまいます。

入力フォームの入力内容によっては、漏洩や改ざん、削除などできてしまうと言うことですね。

これがSQLインジェクションです。

2.SQLインジェクション対策(PHPでの実装例)

文字エンコーディングを指定する
文字エンコーディングを utf8 として DB に接続

qiita.rb
$dbh = new PDO('mysql:host=127.0.0.1;dbname=test;charset=utf8', 'user', 'password');

プレースホルダで実装する

qiita.rb
$sql = "SELECT USER_ID,PASSWORD FROM USER_TBL WHERE USER_ID = ? "
$stmt = $dbh->prepare($sql)
$stmt->execute($userid)

1行目と2行目でUSER_IDに値の入ってないSQL文を組み立てます(プレースホルダー)。
3行目でUSER_IDに値を割り当てます(バインド)。

こうすることにより、SQL文とバインド値は個別にDBに送られ、構文解析されるので、バインド値に悪意あるSQL文が挿入されても、その実行を阻止することができます。

↓↓記事が出来次第Link貼って行きます↓↓
No.01 SQLインジェクションとは?
No.02 クロスサイトスクリプティングとは?
No.03 クロスサイトリクエストフォージェリとは?
No.04 ディレクトリトラバーサルとは?

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

[Laravel]テキスト中のURLをリンクに自動で置換する

概要

テキスト中にあるURLを自動でリンクに置換することでフロント側でリンク化する手間が省けるのでバックエンドで処理をしてみました。

URLをリンク化する

今回はテキスト中にURLの行のみのがある場合にリンク化させます。文章中のURLは、リンク化しない正規表現にしました。

https://test  //リンク化
https://test テスト   //無視

$textのURLをリンク化

public static function replaceUrl($text)
    {
        $texts = explode(PHP_EOL, $text); //PHP_EOLは,改行コードをあらわす.改行があれば分割する
        $pattern = '/^https?:\/\/[^\s  \\\|`^"\'(){}<>\[\]]*$/'; //正規表現パターン
        $replacedTexts = array(); //空の配列を用意

        foreach ($texts as $value) {
            $replace = preg_replace_callback($pattern, function ($matches) {
            //textが1行ごとに正規表現にmatchするか確認する
                if (isset($matches[1])) {
                    return $matches[0]; //$matches[0] がマッチした全体を表す
                }
            //既にリンク化してあれば置換は必要ないので、配列に代入
                return '<a href="' . $matches[0] . '" target="_blank" rel="noopener">' . $matches[0] . '</a>';
            }, $value);
            $replacedTexts[] = $replace;
            //リンク化したコードを配列に代入
        }
        return implode(PHP_EOL, $replacedTexts);
        //配列にしたtextを文字列にする
    }

使用したメソッド

explode — 文字列を文字列により分割する
(https://www.php.net/manual/ja/function.explode.php)
preg_replace_callback — 正規表現検索を行い、コールバック関数を使用して置換を行う
(https://www.php.net/manual/ja/function.preg-replace-callback.php)
implode — 配列要素を文字列により連結する
(https://www.php.net/manual/ja/function.implode.php)

使っている正規表現について

$pattern = '/^https?:\/\/[^\s  \\\|`^"\'(){}<>\[\]]*$/' 

^ 先頭にhttpsまたはhttpにマッチする
\ 直後の正規表現記号を エスケープ
[^...]角括弧に含まれる文字以外にマッチ
ここでは、半角、全角スペースとURLで除外される記号以外とマッチさせています
* 直前の文字が 0回以上 繰り返す場合にマッチします。最長一致。
? 直前の文字が 0個か1個 の場合にマッチします。最長一致。

あとがき

文字列を改行ごとに分割して、分割したものが正規表現にマッチした場合URLをリンク化し、
それをまた文字列に変換したりとするなど色々考えたので勉強になりました。
正規表現もURLとマッチするものを考える作業が楽しかったです。

参考記事

(https://qiita.com/sukobuto/items/b6cdfa966b29823c62f0)

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

Laravel 5.8でオリジナルのイベントを定義してみた話

はじめに

こちらの記事は、社内knowledgeからの移行記事になります。

Laravelで自作イベントを定義するまでの一連の流れ。

【参考にした公式】

【参考記事】
- Laravel5.7でEventを利用してみる - qiita

【ソース】
- GitHub

環境

  • Laravel 5.8.23

本編

1.イベントとリスナをサービスプロバイダに定義

application/app/Providers/EventServiceProvider.php
protected $listen = [
    'App\Events\TaxIncreased' => [
        'App\Listeners\TaxIncreasedNotification'
    ],
];

2.Artisanコマンドでイベントとリスナを作成

# php artisan event:generate
Events and listeners generated successfully!

3.リスナにイベント処理を定義

今回は発生したイベントのオブジェクトを返すだけ。

application/app/Listeners/TaxIncreasedNotification.php
public function handle(TaxIncreased $event)
{
    return $event;
}

4.イベントを定義

application/app/Events/TaxIncreased.php
public $name;
public $price;
public $taxRate;
public $taxIncludingPrice;

/**
 * TaxIncreased constructor.
 *
 * @param string $name
 * @param int $price
 * @param bool $isReduceTax
 */
public function __construct(string $name, int $price, bool $isReduceTax){
    $this->name  = $name;
    $this->price = $price;
    $this->taxRate = ($isReduceTax) ? 0.08 : 0.10;
    // 税込み価格計算
    $this->taxIncludingPrice = (int) $this->price * ( 1 + $this->taxRate);
}

5.イベントを呼び出す

今回はコントローラのアクションからイベントを呼び出す。

application/app/Http/Controllers/HomeController.php
 public function index()
 {
     $eatIn   = event(new TaxIncreased('タピオカ',1000,false))[0];
     $takeOut = event(new TaxIncreased('タピオカ',1000,true ))[0];

     return view('home',compact(['eatIn','takeOut']));
 }

結果

軽減税率イベントが発火した。

image01.png

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

Laravel5.8でSlackに通知(Notifications)を送ってみた話

はじめに

こちらの記事は、社内knowledgeからの移行記事になります。

初めての技術投稿で探り探りな面があります。

Laravelに搭載されている通知(Notifications)機能を使って、
ログインしたときにSlackに通知を送る機能を作成してみました。

不正ログイン通知や購入処理完了時のメッセージ送信などに使えそうですね。

今回のコード

【参考にした公式】
- 公式(英語)
- ReaDouble

なお、ログインイベントのリスナー設定は省略します。
GitHubにコードはあります。

環境

  • Vagrant(Homestead)
  • Laravel 5.8.23

Slackの設定

  1. 送信したいワークスペースの管理画面(https://[ワークスペース名].slack.com/apps) から、投稿したいチャンネルを選択してIncoming Webhookを追加する。

image01.png

  1. 追加後の画面からWebhook URLを回収する。 ***

image02.png

パッケージのインストール

composer require guzzlehttp/guzzle
composer require laravel/slack-notification-channel

通知クラスの作成

下記のコマンドでSlackという通知クラスが作成されます。
viaメソッドで複数定義するとどうなるかは試してみる。

php artisan make:notification Slack

通知クラス(App\Notifications\Slack)

Notification.php
<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\SlackMessage;

class Slack extends Notification
{
    use Queueable;

    protected $content;
    protected $channel;
    protected $name;

    /**
     * Create a new notification instance.
     * @param string $message
     * @return void
     */
    public function __construct(string $message)
    {
        $this->channel  = env('SLACK_CHANNEL');
        $this->name     = env('SLACK_NAME');
        $this->content  = $message;
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['slack'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed $notifiable
     * @return SlackMessage
     */
    public function toSlack($notifiable)
    {
        return (new SlackMessage)
            ->from($this->name, ':ghost:')
            ->to($this->channel)
            ->content($this->content);
    }

}

ログインイベントのリスナーを作成

ログイン時に通知を送信するためのクラスを作成する。

ログイン イベントリスナークラス(App\Listeners\LoginListener)

<?php

namespace App\Listeners;

use Illuminate\Auth\Events\Login;
use Illuminate\Http\Request;

use App\Notifications\Slack;
use App\Notification\Slack\SlackRepository;
use Illuminate\Support\Facades\Notification as FacNotification;

class LoginListener
{
    protected $slackRepository;

    /**
     * Create the event listener.
     *
     * @param Request $request
     * @param SlackRepository $slackRepository
     */
    public function __construct(Request $request, SlackRepository $slackRepository)
    {
        $this->request = $request;
        $this->slackRepository = $slackRepository;
    }

    /**
     * Handle the event.
     *
     * @param  Login  $event
     * @return void
     */
    public function handle(Login $event)
    {
        //ログイン成功時の処理

        // リポジトリで通知を送信します。
        $this->slackRepository->notify(new Slack("リポジトリ:{$event->user->name}"));

        // ファサードで通知を送信します。
        FacNotification::route('slack', env('SLACK_WEBHOOK_URL'))
            ->notify(new Slack("ファサード:{$event->user->name}"));

        // モデルで通知を送信します。
        $event->user->notify(new Slack("モデル:{$event->user->name}"));
    }
}

ログインすると...

絶対通知送信するマンに煽られる。:scream::scream::scream:

image03.png

まとめ

  • Laravelで通知機能を実装
  • クラスから通知を出す場合
    1. 通知を送りたいクラスでNotifiableをtrait
    2. artisanコマンドで通知クラスを作る
    3. 通知クラスにviaメソッド,to〇〇メソッドを実装
    4. 通知を送りたいクラスにrouteNotificationFor〇〇メソッドを実装
  • Notification ファサードを使う場合
use Illuminate\Support\Facades\Notification;

Notification::route($channel,$send)
                ->notify($clsNotification));

参考

その他の参考はこちら。

  1. RitoLabo - LaravelでSlack通知を実装する~ソーシャルではなく開発者/管理者としてのSlack通知~
  2. Laravel Notifications – Easily send quick updates through Slack, SMS, Email, and more
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[php] switchで比較演算を使うときの注意

これに似たコードをレビューしていて

$age = 10;

switch ($age) {

  //年齢が20歳以上、50歳以下
  case $age > 20 && $age < 49:
    echo '21~49歳です。';
    break;

  //年齢が50歳以上
  case $age > 50:
    echo '50歳以上です。';
    break;

  default:
    echo "該当しません。";
    break;
}

出力: 該当しません。

で、気になったので、

$age = 0;

switch ($age) {

  //年齢が20歳以上、50歳以下
  case $age > 20 && $age < 49:
    echo '21~49歳です。';
    break;

  //年齢が50歳以上
  case $age > 50:
    echo '50歳以上です。';
    break;

  default:
    echo "該当しません。";
    break;
}

出力: 21~49歳です。

ん?

該当しませんじゃないの?
(ていうか私はswitchに比較条件入れようとそもそも思わないですが)

1以上は 「該当しません」が出力されます。
0のときだけ先頭が評価されます。

教えてえろいひと。

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

【Laravel】Carbonで今が上期下期を判断する

Laravelを用いてますが、Carboncomposerから入れれるので同じです。

上期は基本的に4月から9月末、下期は10月から3月末のようなので、そのように定義します。

今回はweb.phpにコールバックに書いていきます

web.php
Route::get('/',function(){
    $start = today()->month(4)->firstOfMonth();
    $end = today()->month(9)->endOfMonth();
});

上期の開始と終了を定義しました。
today()はLaravelに用意されているヘルパです。
new Carbon('today')と同等になります。

web.php
Route::get('/',function(){
    $start = today()->month(4)->firstOfMonth();
    $end = today()->month(9)->endOfMonth();
    echo today()->between($start , $end ) ? '上' : '下');
});

あとは、今日が上期の範囲内か判断しているだけです。

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

if文の正しい理解

if文の正しい理解

対象者

これからプログラミングを勉強する人

if文とは

if(式){
文
}

式が TRUE と評価された場合、 PHP は文を実行します。FALSE と評価された場合は、これを無視します。どのような値が FALSE と評価される

以上の事がif文である。
TRUEの場合とは以下の場合。

if(true){
文
}

ここで問いです。
問1.以下の場合はTrueですか?falseですか?

if(1){
}

迷う必要はないですね笑笑
答えはTrueです。
1はTrue、0はfalseとなります。

以上です。

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

【Laravel】データベースを作成しよう

こんにちは!
今回はデータベースにデータを保存できるようにすることを最終地点として説明します
大まかな流れは以下の通りです
1. 環境変数を設定する
2. データベースを作成する
3. データベースに接続する
4. データベースにデータを保存する

では、始めます!!

環境変数の編集

環境変数を編集していきます
環境変数は使用するOS上でのルールを決めている変数というイメージです。
ここで編集するファイルは二つです

.envファイルの編集

.envファイルを編集します
下記のように編集していきましょう
データベースの名前はご自身のアプリケーション名に対応させてください
DB_USERNAMErootDB_PASSWORDsecretで設定しましょう

.env(一部) 編集前
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=

.env(一部) 編集後
DB_DATABASE=laravel-project
DB_USERNAME=root
DB_PASSWORD=secret

database.phpの編集

.envに合わしてdatabase.phpも編集しましょう

config/database.php
'mysql' => [
//                     :
//                     :
     'database' => env('DB_DATABASE', 'laravel-project'),
     'username' => env('DB_USERNAME', 'root'),
     'password' => env('DB_PASSWORD', 'secret'),
//                     :
//                     :
],

データベース作成

MySQLにログインして、データベースを作成しましょう!
MySQLにrootユーザーでログインします。

$ mysql -u root

MySQLにログイン完了後、laravel-projectというデータベースを作成します

mysql> CREATE DATABASE `laravel-project`;

下記のコマンドでデータベースが作成されているか確認しましょう

mysql> show databases;

データベース接続

上で作成したデータベースに接続しましょう

ターミナル
$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.3.9-1+ubuntu18.04.1+deb.sury.org+1 — cli) by Justin Hileman
>>> DB::connection();
=> Illuminate\Database\MySqlConnection {#2891}

テーブル作成

マイグレーションして、テーブルを作成します。
マイグレーションする前に少し準備をします。

文字列の最大文字数を191文字にする

マイグレーション時にエラーになるので設定しましょう

app/Providers/AppServiceProvider.php
    public function boot()
    {
        \Schema::defaultStringLength(191);
    }

では、下記のコマンドでマイグレーションを行い、テーブルを作成しましょう

ターミナル
$ php artisan migrate

テーブルの作成が完了しました。

データ作成

一度に複数のデータを作成しましょう!!
まず、下記のコマンドを実行するとUsersTableSeeder.phpが生成されます。

ターミナル
$ php artisan make:seeder UsersTableSeeder

生成されたUsersTableSeeder.phpのRun関数内に下記のように追記しましょう

database/seeds/UsersTableSeeder.php
    public function run(){
        DB::table('users')->insert([
            'name' => 'test1',
            'email' => 'test1@test.com',
            'password' => bcrypt('test1') 
        ]);
    }

次に、DatabaseSeeder.phpのRun関数内をコメントアウトしてください

database/seeds/DatabaseSeeder.php
    public function run()
    {
        $this->call(UsersTableSeeder::class);
    }

上記で編集したファイルを元にデータを作成しましょう

$ php artisan db:seed --class=UsersTableSeeder

コンソールから作成されたデータを確認しましょう

$ php artisan tinker

>>> use App\User
>>> User::all()

上記のコマンドでテーブル内のデータが表示されます
表示されれば完了です!!

疑問、気になるところがございましたら、質問、コメントよろしくお願いします!!!

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

[PHP] 親の親のコンストラクタを呼び出す方法

PHPのコンストラクタ、__construct()。親クラスのコンストラクタを呼び出すときはparent::__construct()で呼び出せます。では、親の親というか、祖父母というか、2等身以上離れたクラスのコンストラクタを呼び出すにはどうするのでしょう?親クラスのコンストラクタを実行せず、2等身先のコンストラクタを呼び出したい場合です。

対象のクラス名::__construct()

↑のとおりです。感覚的にstaticな呼び出しと同じ書き方なので、プロパティの設定が意図通り動作するのか不安になりますが、大丈夫なようです。

確認したバージョンは7.1.5とか7.3系。5.6系でもいけそう…?

コード例はこちら。C1 -> C21 -> C321という流れで継承しています。

<?php
class C1
{
    // 動作確認用のプロパティ。各コンストラクタで値を設定。
    protected $prop;
    function __construct()
    {
        // C1のコンストラクタを実行した証としてC1を設定
        $this->prop = "C1";
    }
    // 動作確認用の出力関数
    function echo()
    {
        echo $this->prop . PHP_EOL;
    }
}

// C1を親に持つクラス
class C21 extends C1
{
    function __construct()
    {
        // C21のコンストラクタを実行した証としてC21を設定
        $this->prop = "C21";
    }
}

// C1を祖父母、C21を親に持つクラス
class C321 extends C21
{
    function __construct()
    {
        // C321のコンストラクタを実行した証としてC321を設定
        $this->prop = "C321";
        $this->echo(); // -> C321

        // C321の親 = C21のコンストラクタ。prop上書き。
        parent::__construct();
        $this->echo(); // -> C21

        // C1のコンストラクタ。prop上書き。
        C1::__construct();
        $this->echo(); // -> C1

        // parentではなくC21と直接指定も可能。prop上書き。
        C21::__construct();
        $this->echo(); // -> C21
    }
}

// C321のコンストラクタを実行
new C321();

余談 系譜にいない先祖クラスのコンストラクタを呼び出したら?

当たり前ですがエラーになります。cannot be called statically。コード例はこちら。

// C1を親に持つ。C21は系譜に含まれない。C1は前のコード例参照
class C41 extends C1
{
    function __construct()
    {
        // C41のコンストラクタを実行した証としてC41を設定
        $this->prop = "C41";
        $this->echo(); // -> C41

        // C41の親 = C1のコンストラクタ。prop上書き。
        parent::__construct();
        $this->echo(); // -> C1

        // C1のコンストラクタ。prop上書き。
        C1::__construct();
        $this->echo(); // -> C1

        // C21のコンストラクタ。親にいないからエラー
        C21::__construct(); // error
        $this->echo(); // ↑でエラーなので実行されない
    }
}

// C41のコンストラクタを実行
new C41();

おわりに

そもそも親の親のコンストラクタを直接呼び出すべきでない、呼ぶのは親クラスのコンストラクタだけで、その中で祖父母コンストラクタを呼びだすべき…なんですが、横着したいときにでも知ってると便利かも?

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

Re: 10秒で衝突するUUIDの作り方

元ネタは下記リンクを参照。
「UUID生成はライブラリを使え 自分で書くな」との結論は全く同意。

10秒で衝突するUUIDの作り方 - Speaker Deck
https://speakerdeck.com/tanakahisateru/10miao-dechong-tu-suruuuidfalsezuo-rifang

セキュアコーディング

 元ネタ前半の実装のように、アプリケーション開発者が乱数シードを指定して乱数を生成するような実装だと、第三者がシードの値を推測して「次に生成されるUUIDを予測する」ことができるかもしれない。(下記リンクはJavaにおける類例の解説である。)

MSC02-J. 高品質の乱数を生成する
https://www.jpcert.or.jp/java-rules/msc02-j.html

また、生成される可能性のあるUUIDの種類が少ない場合、第三者が総当たりで「どれでもいいので既存のUUIDのどれかに衝突させる」ことができるかもしれない。

 例えばセッションIDを第三者が上述のような方法で推測または意図的に衝突させると、セッションハイジャック攻撃が可能になる場合がある。セッションIDは推測困難な方法で生成するべきである。

OWASP CheatSheet - Session ID Generation and Verification: Permissive and Strict Session Management
https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html#session-id-generation-and-verification-permissive-and-strict-session-management

The session tokens should be handled by the web server if possible or generated via a cryptographically secure random number generator.

 では、どんな乱数生成はセキュアな必要があり、どんな乱数生成はセキュアでなくてよいか? 「生成された乱数を他人が知った場合、何にアクセスしてどのような操作ができるようになるか」によって決まる。 個人情報を含むWebアプリケーションのセッションID生成はセキュアな必要がある。Windowsアプリのソリティアで初期配置を決める乱数の生成はセキュアでなくてもよいように思う。

暗号学的に安全な実装の例

いずれも PHP7

hex

php - Generating cryptographically secure tokens - Stack Overflow
https://stackoverflow.com/questions/18830839/generating-cryptographically-secure-tokens

$token = bin2hex(random_bytes(16));

英数

PHP random string generator - Stack Overflow
https://stackoverflow.com/questions/4356289/php-random-string-generator/31107425#31107425

英数記号

上記リンクの英数ランダム文字列生成を改変、高速化

<?php


function random_str(
    int $length = 20
): string {
    if ($length < 1) {
        throw new \BadMethodCallException('Length must be a positive integer');
    }
    // $keyspace length should be (1<<6) = 64
    $keyspace = '-_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

    $randomStr = [];
    while (true) {
        $randomInt = random_int(0, 1 << (10 * 6));
        for ($i = 10; $i > 0 ; $i--) {
            $randomStr []= $keyspace[$randomInt % 64];
            if (count($randomStr) >= $length) {
                break 2;
            }
            $randomInt = intdiv($randomInt, 64);
        }
    }
    return implode('', $randomStr);
}

Hope this helps.

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

Local (Beta) v5.0.x で PhpStom (Visual Studio Code) で Xdebugを有効にする方法(PHP Snifferも)

概要

ものすごくハマったのでメモします(macOS High Sierra環境)

普段はプログラミングをしないのに、開発環境作りに時間がかかるなんて・・・。そんな思いをしないためのメモです。

結論は、

  • xdebug の設定で、xdebug.remote_connect_back=Off とする

以下、WordPressの開発環境構築も含め、ざっと説明します。

Local by Flywheel

2019.11.26現在、macOS high Sierra でWebサイトにアクセスすると、「ver5.0.x」がダウンロードされる。インストールしたら、思いっきり「Beta」と書いてある。

利点は「2倍以上の高速化」。起動も、再起動も、動作も早い。

(Virtualboxではなく、macのDockerを使っているのかしら。詳しく知るほどの知識はありません)

欠点は、便利なAddonと、カスタマイズが一切なくなったこと。そのうち、実装されるらしい。Betaだからないとのこと。

重要: WordPressの準備と、PHPの設定変更

  • Query Monitor プラグインをインストール(何かと便利)
  • PHPの設定を変更する(VMを再起動すること)
[xdebug]

(もともと何か書いてある)

xdebug.remote_enable=1
xdebug.remote_autostart = 1
xdebug.remote_port="9000"
xdebug.profiler_enable=0
xdebug.show_local_vars = 1

xdebug.remote_connect_back=On はしない。PhpStormは、高機能が故に、この設定があるとうまくいかない。vscodeは平気だった。

補足: Local by Flywheel (3.x) から 5.0.xへ

v3系で、仮想環境(WordPress)を export します。zipファイルができます。これを、新しいLocal (by Flywheelをなくして、Localと呼ぶらしい。あるいは、Local lightning?)に、importする。

PHP Code Sniffer

蛇足ですが、情報が古かったりするので本家で調べて、その方法を使いました。本家(WordPressのCode Snifferの説明)では、プロジェクトの中に、Code Snifferを入れることを推奨しているが、とりあえず、無視。

以下のような手順で、Code Sniffer をインストール

  • homebrew をインストール
  • homebrew で composer をインストール
  • composer で以下のようなコマンドでインストール
composer global require "squizlabs/php_codesniffer=*"
composer global require phpcompatibility/php-compatibility
composer global require wp-coding-standards/wpcs
composer global require dealerdirect/phpcodesniffer-composer-installer

dealerdirect/phpcodesniffer-composer-installer を入れると、code snifferの設定が省ける(自動でやってくれる)。WordPressのgithubにて推奨されてました(for youとか書いてました)。

.bash_profile に追記。ターミナルを再起動(sourceコマンドがかっこいい)。

export PATH=$HOME/.composer/vendor/bin:$PATH
source ~/.bashrc

Visual Studio Code + Xdebug

参照 : https://gist.github.com/ahmadawais/d6e809d45b8103b2b3a79fa8845f9995

準備

  • visual studio code をインストールする
  • 以下の拡張を入れる
    • Wordpress Development
    • phpcs
    • php sniffer
    • php intellisense
    • php extension pack
    • php debug

Workspaceの作り方

Localの ドメイン/app/public/ をVSCodeで開く(ホームのLocal sites です)。

次にサイドバーのDebugアイコンをクリックし、歯車アイコンをクリックし、PHPを選ぶ。 .vscode/launch.js が作られるので、それを編集する。

_2019-11-26_15.48.51.png

上記のように、以下を追加。コンマを直前に忘れずに(jsonとして正しく書くために)。

"pathMappings": {
    "/app/public": "${workspaceRoot}"
}

あとは、デバッグテストする。他の有用なサイトをご覧ください。

Code Sniffer 設定

サイドバーのギアアイコンをクリックし、設定を呼び出す。

PHPCS と検索する。

  • PHP Sniffer: RUN で onTypeにした(せっかちなんで)
  • PHP Sniffer: で WordPress を記述

スペースではなく、タブを使う必要があるので

  • insert space で検索し、スペースを入れるのではなく、tab を使うように設定

PhpStorm の設定

プロジェクト作成

  • WordPressプラグインを選ぶ
  • Location、WordPress Installation path 共に、 app/public を指定する
  • OKする

すると、WordPressサポート関連をするか?と聞かれるので、OKをしていく。

Code Sniffer

  • Language & Frameworks -> PHP -> Quality Tools を開く
  • Code Sniffer の configuration の ... をクリックする
  • PHP Code Sniffer のパスを設定する
    • フォルダアイコンをクリック
    • Cmd + Shift + . で隠しファイル・フォルダを表示状態にする
    • ホームの .composer/vendor/bin/phpcs を選択する
    • 同様に、phpcbf も設定する
  • validate でOKが出たら良し

次に、inspections の設定をする。色々やることがあってややこしいが、案内が丁寧に出る。ただし、以下の注意が必要(2019.2.4時点のバグかもしれない)

  • Editor > Inspections > PHP > Quality tools > PHP Code Sniffer validation にチェックを入れたら、 一旦、OKでダイアログを閉じる

それから、Preferenceを開き直す。そして、Coding Standard に WordPress を選ぶ。選択できるようになっているはず。

Xdebug

右上のデバッグ用のボタンの「add configuration」をクリックする。ダイアローグ画面の左上の + を押す(テンプレートは触らない。ややこしい)。PHP Web Page を選ぶ。

わかりやすいように、PHP Web Pageの設定を Local by Flywheel と名付ける。

Configurationの Server: の ... をクリックする。サーバーを追加する必要があるので、+を押して追加。Name:はまたしてもLocal by Flywheelとする(何でもいい)。Hostは、localhost ではなく、Localでつけた xxx.local とする。OKする。

一応、validation しての良いだろう。

次に、デバッグのための「リッスン状態」にする。先のボタンの横ら辺にある。

初めて、デバッグするときに、

  • incoming connection from xdebug

と出る。ここで、WordPressがインストールされている index.php を設定することで、デバッグができるようになる。

わかれば、作業は難しくない・・・。

蛇足

Local by Flywheel (v3) は、phpstorm用のボタンがあったりして、便利だった。でも、軽量なLocal v5は、すごくいい。苦労はしたが、Local v5を使っていけるので、気分が良い。

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

Address already in use でPHPのビルトインサーバーが立ち上がらない時の対処方法

phpのビルトインサーバーを立ち上げようとした際に、

php -S 192.168.33.10:8000

のコマンドを実行すると、

Failed to listen on 192.168.33.10:8000 (reason: Address already in use)

等とエラーが出てしまう時の対処方法のメモ。

解決手順

1.使用しているPID番号(プロセスID)を確認

ps ax | grep php

ターミナルで上記のように入力すると、現在しているポートが表示される。

[vagrant@localhost My_php]$ ps ax | grep php
 9375 pts/0    S+     0:00 php -S 192.168.33.10:8000 -t public_html/

※一番左の数字が「PID番号」なので、上記の例だと「9375」

2.既に解放しているプロセスを終了する

kill PID番号

3.再度、php -S 192.168.33.10:8000 を実行

php -S 192.168.33.10:8000
PHP 7.1.33 Development Server started at Mon Nov 25 03:37:42 2019
Listening on http://192.168.33.10:8000
Document root is /home/vagrant/My_php
Press Ctrl-C to quit.

これでビルトインサーバーが立ち上がるはずです。

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