20190627のPHPに関する記事は12件です。

環境変数を設定してPHPファイルをコマンドラインから実行する方法

PHPファイルをコマンドラインから実行する際、環境ごとに動作を変えるために変数を設定する。

バッチ処理などの開発で多用するのでメモ。

シェル変数に設定

ENV=master php index.php

ENV=masterと書くことで、シェル変数を設定できる。
シェル変数とは、そのプロセスのみ有効な変数。

ちなみにPHPで変数の取得方法はこちら

index.php
$env = getenv("ENV");

//これでも取れる
$env = $_SERVER["ENV"];

コマンドプロンプトの場合は?

上記の環境変数の設定方法はLinuxコマンドなので、コマンドプロンプトだとエラーがでる。

コマンドプロンプトの場合は、こちら。

set ENV=master&php index.php

コマンドプロンプトではset を使用することで、環境変数の設定が可能。

かつコマンドを複数同時に実行するときは& でつなげてやる必要がある。

プロセスごとの変数はどうやって設定するのか?そのあたりの理解がまだまだ足りない。

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

phpunit.xmlの設定が反映されない

問題:phpunit.xmlが反映されない

        <env name="APP_ENV" value="testing" />

Laravelの開発で phpunit.xml の環境名の上書きを下記のテストで確認したところ、反映されませんでした。

tests\Unit\DemoTest.php

use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

class DemoTest extends TestCase
{
    /**
     * @test
     */
    public function 環境確認()
    {
        $this->assertEquals('testing', $this->app->environment());
    }
}
   │ Failed asserting that two strings are equal.
   │ --- Expected
   │ +++ Actual
   │ @@ @@
   │ -'testing'
   │ +'local'
   │
   │ /home/vagrant/code/demo-vue-practice/tests/Unit/DemoTest.php
   │

Time: 2.09 seconds, Memory: 16.00 MB

解決策: force=trueを設定

https://stackoverflow.com/questions/45922358/why-phpunit-is-not-getting-the-correct-app-env-as-specified-in-phpunit-xml

        <env name="APP_ENV" value="testing"  force="true"/>

またphp artisan config:clearも行う必要がありそうでした。
https://stackoverflow.com/questions/48227569/failure-to-set-app-env-to-testing-for-unit-testing-in-laravel-5-5

これで先のテストが通りました。

Unit\DemoTest
 ✔ 環境確認

Time: 2.07 seconds, Memory: 16.00 MB

以上です。

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

Swift_Message で CC とか BCC を取得する

Laravel が使っている Swift_Mailer というライブラリを使って色々独自実装を持ちたい時で、生成されたメールデータに用事がある時に毎回忘れて感覚で使ってエラーだすので書き残す。

メール本文やヘッダに持つデータは Swift_Message に格納される事になる。
そのため、表題の通り CC や BCC を取りたい場合 (それ以外も) このクラスの所有する API を使う。

$mailer->getCc();
$mailer->getBcc();

それぞれはこれだけの話なんだけど、上記で取得出来るデータの構造が連想配列で、よりにもよって key にアドレスが格納されている。

[
  "sample@sample.com" => null,
]

こんな感じ。多分、実装意図としては、連想配列の key に入れる事で集合と同じ効果を狙っている (挿入されたメールアドレスが重複した場合に 1 つにまとまる事を期待) と思うんだけど、取得する時までこの構造のままなので実に困る。(単純に考えると、配列として取得できる気がするのが困り所)

BCC に設定する時に複数を設定する場合と 1 つしか絶対に入れない時があり、今回は 1 つだけ欲しかったので下記で対応した。

key($mailer->getBcc());

全部を配列で取得する必要がある場合は下記とか。

array_keys($mailer->getBcc());
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

サイトのプレビュー画像(og:image)を取得するAPIを作成

  • 仕様言語 PHP
  • フレームワーク Laravel

やりたいこと

サイトのURLから、プレビュー画像のURLを取得

方法

Goutteを使用し、metaタグのOGPを探す
OGPからプロパティog:imageがあった場合、画像URLを返す
OGPについて

実装

スクレイピング用のライブラリGoutteをインストール

$ composer require weidner/goutte

Configファイルの編集

config/app.php
'providers' => [
  ...
  Weidner\Goutte\GoutteServiceProvider::class,
  ...
],
'aliases' => [
  ...
  'Goutte' => Weidner\Goutte\GoutteFacade::class,
  ...
],

ルートに下記を追加

http://127.0.0.1:8000/api/scrape?url=https://www.facebook.com/
このようなAPIを実行すると、プレビュー画像のURLが返ってくる想定

route/api.php
Route::group(['namespace' => 'API', 'as' => 'api.'], function() {
    Route::get('scrape', 'ScrapeController@index')->name('scrape');
});

controllerの記述

Controllers/API/ScrapeController.php
<?php

namespace App\Http\Controllers\API;

use Goutte\Client;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class ScrapeController extends Controller
{
    public function index(Request $request)
    {
        $client = new Client();
        // 受け取ったURLへリクエストを送信
        $crawler = $client->request('GET', $request->url);
        // metaタグを取得し、propertyがog:imageのものの場合は、contentの中身を返す
        // propertyがog:imageでないものはnullを返す
        $contentList = $crawler->filter('meta')->each(function ($node) {
            if ($node->attr('property') === 'og:image') {
                return $node->attr('content');
            }
            return null;
        });

        // valueがnullでない(URLが格納されている)ものだけを返す
        // (goutteのfilter()でもっと上手くフィルタリングできる方法があればこの処理は不要。。)
        foreach ($contentList as $key => $content) {
            if ($content === null) {
                continue;
            }
            $imageUrl = $contentList[$key];
        }

        // URLが取得できていなかった場合はNULLを返す
        return response()->json([
            'image_url' => $imageUrl ?? NULL;
        ]);
    }
}

結果

APIを実行

$ curl http://127.0.0.1:8000/api/scrape?url=https://qiita.com

実行結果

https://cdn.qiita.com/assets/qiita-fb-2887e7b4aad86fd8c25cea84846f2236.png

実行結果

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

【開発環境構築】誰でもお手軽LAMP環境Scotch-box 3.5 使ってみる

「ローカルにLAMP環境を勉強用に用意したいけどまた1から作るのめんどくさいなー」
ポチポチ

【ラクしてLAMPとかの環境を用意したい人のためのScotch Box】
https://qiita.com/naru0504/items/a14681b030816135b868?sb2

【ラクして環境構築するためのScotch-Boxが2.0になってかなり進化してた。】
https://qiita.com/naru0504/items/560a150943d2251e1ae8

「LAMP環境をラクに用意したいとか思っていたら、いいものを見つけました。」

わぁ!?なんと!
調べてみたところ現在はVersion3.5がリリースされているみたいです。

ということで実際に導入してみました。

前提条件

私のPC環境

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.12.4
BuildVersion:   16E195

Scotch Boxに関して

公式サイト
https://box.scotch.io/
リポジトリ
https://github.com/scotch-io/scotch-box

本文

インストール

公式サイト手順どおりやっていきましょう。

$ cd [インストールしたいディレクトリ]
$ git clone https://github.com/scotch-io/scotch-box.git
    ...
    default: Guest Additions Version: 5.1.21
    default: VirtualBox Version: 5.2
==> default: [vagrant-hostsupdater] Checking for host entries
==> default: [vagrant-hostsupdater] Writing the following entries to (/etc/hosts)
==> default: [vagrant-hostsupdater]   192.168.33.10  scotchbox  # VAGRANT: c545e317eb29acab529f8d8c2d591bb2 (default) / 10c73402-26f2-42d6-98a2-a122365b9dd3
==> default: [vagrant-hostsupdater] This operation requires administrative access. You may skip it by manually adding equivalent entries to the hosts file.
# PCのパスワードを入力
Password:

インストール終わったら  
下記URLにアクセス
http://192.168.33.10/

image01.jpg

TOPページが表示されましたね。

SSHログインしてみよう

$ vagrant ssh
...
MMMMMMMMMMMMMMMXl.:kXNWMMMMMMMMMMMMMMWWXOc.cXMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMXx:;;:clooddddddddoolc:;;:dKWMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMWXOdl:;,,.........,;:cdkXWMMMMMMMMMMMMMMMMM
  ______                      _        ______                ______
 / _____)            _       | |      (____  \              (_____ \
( (____   ____ ___ _| |_ ____| |__     ____)  ) ___ _   _    _____) )___ ___
 \____ \ / ___) _ (_   _) ___)  _ \   |  __  ( / _ ( \ / )  |  ____/ ___) _ \
 _____) | (__| |_| || |( (___| | | |  | |__)  ) |_| ) X (   | |   | |  | |_| |
(______/ \____)___/  \__)____)_| |_|  |______/ \___(_/ \_)  |_|   |_|   \___/

For help, please visit box.scotch.io or scotch.io. Follow us on Twitter @scotch_io and @whatnicktweets.

Last login: Wed May 31 01:25:33 2017 from 10.0.2.2
$ 

sshでログインできました。
LAMP環境構成されているか確認してみよう。

# OS
$ cat /etc/issue
Ubuntu 16.04.2 LTS \n \l

# Apache
$ apachectl -v
Server version: Apache/2.4.18 (Ubuntu)
Server built:   2017-05-05T16:32:00

# PHP
$ php -v
PHP 7.0.18-0ubuntu0.16.04.1 (cli) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.0.18-0ubuntu0.16.04.1, Copyright (c) 1999-2017, by Zend Technologies

# MySQL
$ mysql --version
mysql  Ver 14.14 Distrib 5.7.18, for Linux (x86_64) using  EditLine wrapper

全部入ってる!!!

ドキュメントルートを設定しよう

/etc/apache2/sites-available/000-default.conf
の設定を書き得えればいいみたい

念の為デフォルト設定をコピー

$ cp 000-default.conf 000-default_origin.conf

000-default.confを編集

$ sudo vim 000-default.conf
<VirtualHost *80:>  
    ServerAdmin webmaster@localhost  
    DocumentRoot /var/www/public  
    ErrorLog ${APACHE_LOG_DIR}/error.log  
    CustomLog ${APACHE_LOG_DIR}/access.log combined  
    <Directory "/var/www/public">  
        Options Indexes FollowSymLinks  
        AllowOverride all  
        Require all granted  
    </Directory>  
</VirtualHost>  

↓↓↓

<VirtualHost *80:>    
    ServerAdmin webmaster@localhost  
    DocumentRoot /var/www/html  
    ErrorLog ${APACHE_LOG_DIR}/error.log  
    CustomLog ${APACHE_LOG_DIR}/access.log combined  
    <Directory "/var/www/html">  
        Options Indexes FollowSymLinks  
        AllowOverride all  
        Require all granted  
    </Directory>  
</VirtualHost>  

Apacheを再起動しましょう

# シンタックスチェック
$ apachectl configtest
Syntax OK
# Apacheリスタート
$ sudo service apache2 restart

試しにHTMLを配置してあげましょう。

$ cd /var/www/
$ sudo mkdir html
$ cd html
# 最初からvimも入ってる!
$ vim index.html

Hello World
~                                  
"index.html" 1L, 12C  

:wqで保存後
http://192.168.33.10/
にアクセスするとHello Worldが表示されると思います。

初期画面はどこにいったの?

あくまで一例ですが僕は

# 名前を変更  
$ mv /var/www/public/index.php /var/www/public/doc.php  
# ファイルを移動  
$ mv /var/www/public/index.php /var/www/public/doc.php /var/www/html/  

http://192.168.33.10/doc.php
に移動させました。
他にもポート開けてあげるとかの方法はあると思います。

synced_folderについて

公式のVagrantfileで既にsynced_folderが適応されているので

config.vm.synced_folder ".", "/var/www", :mount_options => ["dmode=777", "fmode=666"] 

ホスト側から編集してもリアルタイムで反映されてると思います。

最後に

WEB界隈は開発環境構築が簡単と聞きますが躓く人も多々いると思うのでお役に立てたら光栄です。
Scotch-boxBOXを使用しないVarant環境構築方法は別記事で書こうとは思ってます。
タイポや嘘が紛れてたら指摘頂けると幸いです。
お読み頂きありがとうございました。

参考記事

【ラクしてLAMPとかの環境を用意したい人のためのScotch Box】
https://qiita.com/naru0504/items/a14681b030816135b868?sb2

【ラクして環境構築するためのScotch-Boxが2.0になってかなり進化してた。】
https://qiita.com/naru0504/items/560a150943d2251e1ae8

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

【php】serialize() VS var_export() VS json_encode() VS http_build_query()

【php】serialize() VS var_export() VS json_encode() VS http_build_query()

結論:json_encodeが早い。

php7環境で下記コードを実行

<?php
$a = array_fill(0, 1000, array_fill(0, 1000, 1));
$max = 1000;

echo "serialize " . microtime() . "\n";
for ($i=0; $i<$max; $i++) {
    if (!($i % 100)) echo $i . "\n";
    $b = serialize($a);
}
echo microtime() . "\n\n";

echo "var_export " . microtime() . "\n";
for ($i=0; $i<$max; $i++) {
    if (!($i % 100)) echo $i . "\n";
    $b = var_export($a, true);
}
echo microtime() . "\n\n";

echo "json_encode " . microtime() . "\n";
for ($i=0; $i<$max; $i++) {
    if (!($i % 100)) echo $i . "\n";
    $b = json_encode($a);
}
echo microtime() . "\n\n";

echo "http_build_query " . microtime() . "\n";
for ($i=0; $i<$max; $i++) {
    if (!($i % 100)) echo $i . "\n";
    $b = http_build_query($a);
}
echo microtime() . "\n\n";

実行結果

serialize 0.13482000 1561615171
0
100
200
300
400
500
600
700
800
900
0.38630600 1561615221

var_export 0.38633600 1561615221
0
100
200
300
400
500
600
700
800
900
0.19411200 1561615319

json_encode 0.19412900 1561615319
0
100
200
300
400
500
600
700
800
900
0.97560400 1561615333

http_build_query 0.97562600 1561615333
0
100
200
300
400
500
600
700
800
900
0.72081200 1561615394
  • serialize 約50秒
  • var_export 約98秒
  • json_encode 約24秒
  • http_build_query 約61秒

結論:json_encodeが早い。

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

LaravelでLeague/Csvを使ってDBから取得したデータをcsvで吐き出す

前提

この記事の続編ですので環境構築などはこの記事を参照してください。
LaravelでLeague/Csvを使ってアップロードされたcsvを読み込みDBに保存する

やりたいこと

Eloquentで取得したデータをcsvに吐き出し、webからダウンロードできるようにしたい。

実装

ClientController.php
public function export()
{
    $csv = \League\Csv\Writer::createFromFileObject(new \SplTempFileObject());

    // csvのヘッダーを配列で渡す
    $csv->insertOne(['id', '名前', '企業', 'メールアドレス']);

    Client::all()->each(function($client) use($csv) {
        $csv->insertOne($client->toArray());
    });

    return new Response($csv->getContent(), 200, [
        'Content-Encoding' => 'none',
        'Content-Type' => 'text/csv; charset=UTF-8',
        'Content-Disposition' => 'attachment; filename="'.'ファイル名.csv'.'"',
        'Content-Description' => 'File Transfer',
    ]);
}

実際の使い方

僕が使った時はServiceクラス作って

ClientController.php
public function exportCSV(ClientCsvExportService $service)
{
    return $service->setHeader(['id', '名前', '企業', 'メールアドレス'])
                ->setFileName(now().'ファイル名.csv')
                ->export();
}

的な感じで抽象化しました。
ClientCsvExportService内でLeague/csvを使ってます。

感想

めっちゃ楽だった。
csvインポートでLeague/csv使った時はShift_JIS対応のためのShift_JISとUTF-8での処理の分岐がめんどかったんです。
楽な書き方がエンコードするとできなくなるみたいなのがあって…
けど、今回はとても楽で良かったです。

参考文献

https://mattstauffer.com/blog/export-an-eloquent-collection-to-a-csv-with-league-csv/
https://csv.thephpleague.com/9.0/connections/output/

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

廃れゆくかも知れない Web Speech API でアシスタントアプリを再稼働したお話

音声アシスタント「HiBot」

https://webmidori.xsrv.jp/app-hibot/

hibot.png

hibot.png

なんの話か

自作アプリの紹介です。

映画「アイアンマン」のラボに登場する AI・ジャーヴィスを見て、
音声アシスタントに仕事や趣味を手伝ってほしいなー、と思って作りました。
もう4年ほど前になります(2015年か2014年…)

稼働条件

  • Google Chrome ※ HTML5 で音声認識が使えるのは Chrome のみ…(iOS 版はなぜか無理?)
  • Chrome なら、PC/モバイルとも対応

使用例

  • 画面を開くと、アシスタントが挨拶します
  • 最初にマイクへのアクセスと、(スマホの場合)ポップアップを開くのを許可してください
  1. 画面のアシスタントをクリックまたはタップ(短時間、マイクがONになります)
  2. 「レシピ検索」と呼びかける→ 「続けてキーワードをどうぞ」と HiBot が答える
  3. 例えば「牛丼」と返事をする→ クックパッドの牛丼のレシピ画面を表示
  4. ※答えられる内容は、画面上にあるリストになります

使用している技術

  • HTML5 (webkitSpeechRecognition, SpeechSynthesisUtterance) ※詳しくは MDN の Web Speech API をご参照下さい
  • CSS
  • jQuery ※ PHP との非同期通信用(近日中に axios に置き換えたい…)
  • PHP ※主にスクレイピングや外部の Web API をたたくため

※ご覧の通り、クラウドサービスは使っていません。HTML5 だけで音声認識/合成を行えるのは素晴らしいです

開発を辞めていた理由

これを作っている最中に Alexa と Google アシスタントが登場したのと、
HTML5 の Speech 系の API が Google Chrome でしか動かない、という事情から
開発をやめていました。

再稼働してみて分かったこと

  • 「音声認識」の HTML API はまだ生きている
  • 「音声合成」の HTML API は2018年で廃止が決定?(注意的なエラーが出たのでそのうち調査します)
  • Google のクラウドサービス: Cloud Speech-to-Textが 台頭しているため、今後、HTML5 での発展は厳しそう
  • いざとなれば Cloud Speech-to-Text に乗り換えればOK(月間60分無料)なので、ツールとして便利に仕上げたい
  • マーケットや天気のウェブ API が、ここ数年で廃止→ その呼びかけは現状除去 (2019.06.26) いずれは再実装します
  • ウェブとつながったサービスは、常にメンテナンスが必要と実感(サービスが停止している時にどうするか、例外処理は必須)
  • 音声合成、音声認識はやっぱり楽しい
  • 言葉と言葉のやりとりより、画面があった方がやはり便利

今、考えていること

  • 音声認識は Google Chrome のみ対応とはいえ、実質無料で使えるし、代替で Cloud Speech-to-Text があるので、開発を続けようという気になった
  • 緯度・経度の情報と連携すれば、現在地情報を元に、天気をはじめ周辺情報を取り出せるので今後はそこを充実させたい
  • ループ処理を実装して、常に音声を待ち受けるようにする
  • 独自に情報収集するページを作って開いたり、Bootstrap のテンプレートから好みのデザインを作り上げたり、ウェブのジャーヴィスにしていきたい
  • 色んな「Bot」を開発する力をつけて、色んなものを自動化していきたい
  • OSS で音声合成、音声認識のソフトウェアがあれば教えてください!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CentOS7でのSimpleSAMLphp環境構築(後編)

はじめに

https://qiita.com/come340/items/2019846f84950f5b46fc
で、続きは今度書くと言ったまま更新していませんでした…。
前記事でSimpleSAMLphp設定ページの表示までできたと思うので次はSP(サービス・プロバイダ)とIdP(アイデンティティ・プロバイダ)を構築します。それぞれ1個ずつサーバを立てておきましょう。(どちらかだけ作るときは1個でいいです)

下記のサイトを参考にさせて頂いております。
https://qiita.com/haya43/items/c74d2710cd9b57d2cbb4

環境

・CentOS Linux release 7.5.1804 (Core)
・Apache/2.4.6
・PHP 5.6.40 ※後述
・SimpleSAMLphp 1.17.2

SP・IdP共通の作業

管理者でログインする

1.adminユーザパスワードを設定
config.phpを編集します

# vi /var/www/simplesaml/config/config.php
config.php
'auth.adminpassword' => '(任意のパスワード)',

2. secretsalt設定
下記コマンドでランダム文字列を生成

# tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' </dev/urandom | dd bs=32 count=1 2>/dev/null;echo

エラーが出たらこっちを試してみてください。

# LC_CTYPE=C tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' </dev/urandom | dd bs=32 count=1 2>/dev/null;echo

生成されたランダム文字列をコピーして再びconfig.phpを編集

config.php
'secretsalt' => '(生成したランダム文字列)',

3.管理者でログイン
SimpleSAMLの設定ページを見ると、右上に"管理者でログイン"と表示されていると思います。
スクリーンショット 2019-06-20 17.31.17.png

ここをクリックするとログイン画面に遷移し、ユーザ名とパスワードを要求されます。ユーザ名はadmin、パスワードは先程設定したものを入力しましょう。

スクリーンショット 2019-06-20 17.40.23.png

4.うまくログインできないとき
ここでうまくログインできない場合があります。いろいろ調べてみるとPHPのバージョンが良くないことが原因らしいので確認します。前記事でインストールしたPHPのバージョンは5.4.~(ちゃんと覚えていないですが…)だったので、要求されているバージョン(5.5.0以上)に合致していないことがよろしくなかったようです。ので、バージョンアップします。

https://blog.s-giken.net/369.html を見ながらバージョンアップしました。5.6.40です。これで再び管理者ログインを試みるとうまくいきました。
なにかうまくいかなかったときは設定タブの"Sanity check of your SimpleSAMLphp setup"をクリックしてみてバージョンが合っているかなど確認するといいかもしれないですね。

IdPの設定

1.saml20-idpを有効化する
config.phpを編集

# vi /var/www/simplesaml/config/config.php
config.php
 'enable.saml20-idp' => true, # falseからtrueに変更

これでIdPとしての機能が有効化されます。
SimpleSAMLの設定ページで設定タブを開いて、左上の欄を確認すると以下のようになっていると思います。
スクリーンショット 2019-06-27 13.17.22.png

2.自己証明書作成

# cd /var/www/simplesaml
# openssl req -newkey rsa:2048 -new -x509 -days 3652 -nodes -subj "/C=JP/ST=Tokyo/CN=idp1.local" -out cert/idp1.local.crt -keyout cert/idp1.local.pem

CN=idp1.localとしていますがこれは自分のホスト名を、idp1.local.crtとidp1.local.pemは自分でわかるように適当な名前をつけます。

saml20-idp-hosted.phpを編集しておきます。(crtとpemのファイル名をserver.crtとserver.pemとした場合はこの手順は不要です)

# vi /var/www/simplesaml/metadata/saml20-idp-hosted.php
saml20-idp-hosted.php
    'privatekey' => '(設定した名称).pem',
    'certificate' => '(設定した名称).crt',

SPの設定

1.自己証明書作成

# cd /var/www/simplesaml
# openssl req -newkey rsa:2048 -new -x509 -days 3652 -nodes -subj "/C=JP/ST=Tokyo/CN=sp1.local" -out cert/sp1.local.crt -keyout cert/sp1.local.pem

だいたいIdPと同じ要領です。

2.default-spの設定
authsources.phpを編集

# vi /var/www/simplesaml/config/authsources.php
authsources.php
    'default-sp' => [
        'saml:SP',

        'privatekey' => 'sp1.local.pem',  # opensslコマンドで設定したファイル名
        'certificate' => 'sp1.local.crt', # opensslコマンドで設定したファイル名

        // The entity ID of this SP.
        // Can be NULL/unset, in which case an entity ID is generated based on the metadata URL.
        'entityID' => 'http://sp1.local/', # 自ホストのURL

        // The entity ID of the IdP this SP should contact.
        // Can be NULL/unset, in which case the user will be shown a list of available IdPs.
        'idp' => null,

ここでidpをnullにしていますが、連携するidpが一つである場合はidpのエンティティIDを入力します。エンティティIDは自分で構築したIdPを用いる場合、SimpleSAMLの設定ページから確認できます。IdPの設定ページで連携タブ>SAML 2.0 IdPメタデータの欄に記載されています。

スクリーンショット 2019-06-27 13.08.34.png

これはIdPの設定を終えてからしか表示されないので先にIdPの設定を行ってください。また、連携したいIdPが複数ある場合はnullにしておくと、実際にIdPログインを行う際にIdPを選択できるようになります。

SP・IdPの連携

IdPのメタデータをSPに登録

IdPメタデータXMLファイルを取ってくる

IdP側の設定ページで連携タブ>SAML2.0IdPメタデータ欄>メタデータを表示
で以下の画面に。
スクリーンショット 2019-06-27 13.28.24.png

メタデータをコピーします。(左上のボタンを押すとクリップボードにコピーされます)

XMLフォーマットをパース

次にSPの設定ページに行き、連携タブ>ツール欄>メタデータをXMLに変換(これはIdPの設定ページでもできるような気がするが検証していないです…たぶんできます)
XMLメタデータパーサの入力欄に先程コピーしたIdPのメタデータを貼り付け、パース。XMLフォーマットがSimpleSAMLphpのメタデータフォーマットに変換されるので再びコピーします。

メタデータをSPに登録

SPのサーバで

# vi /var/www/simplesaml/metadata/saml20-idp-remote.php

先程コピーした変換されたフォーマットをファイルの最後にペースト

saml20-idp-remote.php
<?php
/**
 * SAML 2.0 remote IdP metadata for SimpleSAMLphp.
 *
 * Remember to remove the IdPs you don't use from this file.
 *
 * See: https://simplesamlphp.org/docs/stable/simplesamlphp-reference-idp-remote
 */
$metadata['http://idp1.local/simplesaml/saml2/idp/metadata.php'] = array (
  'entityid' => 'http://idp1.local/simplesaml/saml2/idp/metadata.php',
  'contacts' =>
  array (
  ),
  'metadata-set' => 'saml20-idp-remote',
  'SingleSignOnService' =>
  array (
    0 =>
    array (
      'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
      'Location' => 'http://idp1.local/simplesaml/saml2/idp/SSOService.php',
    ),
  ),

(以下略)

SPのメタデータをIdPに登録

だいたいの流れはIdPの時と同じです。
① 連携タブからXMLフォーマットのSPメタデータを取ってくる
※IdPではsaml20-idpメタデータ欄からメタデータを取ってきましたが、SPではsaml2.0SPメタデータ欄から取ってきます。
② XMLフォーマットをメタデータパーサで変換
③IdPに登録(以下記載)

メタデータをIdPに登録

IdPのサーバで

# vi /var/www/simplesaml/metadata/saml20-sp-remote.php

このファイルは元々いろいろ書いてあるので全部消して先程コピーしたメタデータフォーマットを貼り付けます。不安な人はバックアップファイルを作っておくとよいでしょう。
また、全部消して貼り付けただけだとphpタグがないので<?phpを一行目に書いておくことを忘れずに。

saml20-sp-remote.php
<?php
$metadata['http://sp1.local/'] = array (
  'entityid' => 'http://sp1.local/',
  'contacts' =>
  array (
  ),
  'metadata-set' => 'saml20-sp-remote',
  'AssertionConsumerService' =>
  array (
    0 =>
    array (
      'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
      'Location' => 'http://sp1.local/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp',
      'index' => 0,
    ),

(以下略)

認証モジュールの設定

IdP側の設定では認証モジュールの設定もします。詳しくは公式文書を読みましょう。
https://simplesamlphp.org/docs/stable/simplesamlphp-idp
3番の項目を読むといいです。

今回はexampleauthモジュールを使ってみます。

# cd /var/www/simplesaml
# touch modules/exampleauth/enable
# vi /var/www/simplesaml/config/authsources.php

example-userpassの項目の前後からコメントアウト(/*, */)を消去します。

authsources.php
'example-userpass' => [
        'exampleauth:UserPass',

        // Give the user an option to save their username for future login attempts
        // And when enabled, what should the default be, to save the username or not
        //'remember.username.enabled' => false,
        //'remember.username.checked' => false,

        'student:studentpass' => [
            'uid' => ['test'],
            'eduPersonAffiliation' => ['member', 'student'],
        ],
        'employee:employeepass' => [
            'uid' => ['employee'],
            'eduPersonAffiliation' => ['member', 'employee'],
        ],
    ],

IdPにユーザ設定ができたので、ユーザ名='student'、パスワード='studentpass'でstudentユーザとしてログインできるようになるといった具合です。

接続テスト

SP側の設定ページで認証タブ>設定されている認証元をテスト>default-sp>(IdPを複数登録している場合は選択)>IdP側のログイン画面でユーザ名とパスワードを入力してログイン(student/studentpassなど)

スクリーンショット 2019-06-27 13.58.26.png

IdPでログインできました。やったね!
ちなみに同じ設定をしたSPをもう一つ作っておくと、このログイン作業を一回終えた後にもう一つのSPでもログインしようとしたらすでにログインが終わっている状態になっています。(これがシングルサインオン)

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

自分用 phpstorm プラグインまとめ

毎回あっちこっち探しにいくのが面倒くさいので、個人用ににまとめておきます。

Key Promoter X

よくマウスで操作しちゃっている操作について、ショートカットキーを教えてくれる。めちゃくちゃ便利

Cordigniter

よく使っているフレームワームのやつ。

deep assoc completion

連想配列のキーを教えてくれる。

Sctrach

適当なテキストをその場でかける。

.​ignore

ignoreファイルがファイル作成一覧とかに出てくれる。テンプレートつきでうまし。

RegexpTester

正規表現のテストができる。

Rainbow Brackets

カッコを色分けして見せてくれる。

Translation

さくっと意味の翻訳ができる。

Synonyms

関数の名前付けなどに候補を出してくれる。

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

php-master-changes 2019-06-26

今日は継承時の処理のリファクタリング、ドキュメントの更新、メモリリークの修正、不要テストを削除する修正があった!

2019-06-26

dstogov: Replace previosly checked conditions by ZEND_ASSERT()

dstogov: Remove always true/false conditions, remove dead conde and simplify code.

dstogov: Reorder conditions to minimize number of checks on fast path

petk: [ci skip] Mention HAVE_HASH_EXT

nikic: Fix fpm limit_extensions leak

nikic: Use ldap_destroy instead of ldap_unbind_ext

nikic: Fix xml doc leak in soap

dstogov: Private methods don't have to be duplicated

nikic: Remove stream_socket_sendto.phpt

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

php-master-changes 2019-06-25

この日は preloading のバグ修正、メモリリークの修正、run-tests.php で、非 valgrind 時に USE_ZEND_ALLOC=1 を強制しないようにする修正、分かり辛い goto 利用箇所の修正、継承時の処理のリファクタリング、ドキュメントの更新、opcache で統計情報出力時に誤って符号付きにしていた箇所の修正、phpdbg の off-by-1 の修正、FFI のビットフィールドの操作処理の修正があった!

2019-06-25

dstogov: Fixed bug 78175 (Preloading must store default values of static variables and properties)

nikic: Fix region leak in mb_ereg_replace

nikic: Don't force USE_ZEND_ALLOC=0 in run-tests.php

nikic: Fix EVP_PKEY leak in phar

nikic: Avoid confusing gotos in phar_split_cache_list

dstogov: Keep lowercased parent class name as second argument of DECLARE_CLASS to avoid extra work at run-time

derickr: Update NEWS for PHP 7.4.0alpha2

derickr: Update NEWS for 7.4.0alpha3

dstogov: Prevent useless hash lookups

cmb69: Fix #78202: Opcache stats for cache hits are capped at 32bit NUM

dstogov: Reduce overhead of delayed early binding

dstogov: Set ZEND_ACC_LINKED flag after early binding (for consistency)

nikic: run-tests: Don't die unnecessarily

nikic: Fix stream leak in phar cache_list

nikic: Fix TimeZone leak in intl MessageFormat

nikic: Fix UConverter leak

nikic: Fix SSL_CTX leak in ftp extension

nikic: Fix leak on sqlite3 open error

nikic: Fix CURLINFO_COOKIELIST leak

nikic: Fix out of bounds write in phpdbg

nikic: FFI: Perform bitfield operations byte-wise

dstogov: Cleanup

dstogov: Fixed variance check for abstract constructor during erlay binding

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