Singleton(シングルトン)を使ってみる

 

今回は、ご存知デザパタの
第5章 Singleton 〜たった一つのインスタンス〜
について自分なりにまとめたいと思います。

 

シングルトンって音がかわいいですよね、「トン」とかがw

シングルトン(Singleton)とは

何も考えず、実装をしているとなんども同じインスタンスを生成しがちです。
・指定したクラスのインスタンスが絶対1つしか存在しないことを保証したい
・インスタンスが1つしか存在しないことを、プログラム上で表現したい

そんなときに、インスタンス生成コストを下げるためにも、
Singletonパターンを使います。

 

参考:
PHPで書き換えてくれてるソース
https://github.com/HappyDays-jQuery/GoF/tree/master/src/Singleton

 

 

こんな感じ

全体コード→https://github.com/kin29/DezaPata/pull/4/files

– Singletonクラス
– コンテキスト(使う側)

Singletonクラス

<?php

namespace DP\Singleton;

class Singleton
{
    /**
     * @var Singleton
     */
    //static宣言がされているため、
    //クラスのインスタンス化の必要なしにアクセスできる。
    //ただしprivateなので同クラス内のからしかアクセスできない
    private static $singleton;

    //privateなので、同クラス内からしかインスタンス生成をできない。
    //他のクラスからnew Singletonをするとエラーになる。
    //このクラスではgetInstanceがインスタンス生成をしている。
    private function __construct()
    {
        echo "create SingletonClassInstance\n";
    }

    //すでに$singletonにインスタンスがセットされている場合は、newしない。
    public static function getInstance()
    {
        //$singletonがstatic宣言されているため、
             //$this->singletonでアクセスできない。
        if (is_null(self::$singleton)) {
            self::$singleton = new Singleton();
        }
        return self::$singleton;
    }
}

 

 

contextSingleton.php ←コンテキスト(使う側)

<?php

use DP\Singleton\Singleton;

echo "Singletonクラスを普通にnewしてみる。\n";
new Singleton(); //たぶんおこられる。

外部クラスからnewすると
Singleton::__construct()がprivateなので怒られます。

$ php contextSingleton.php

Singletonクラスを普通にnewしてみる。
PHP Fatal error: Uncaught Error: Call to private DP\Singleton\Singleton::__construct() from invalid context in /Users/XXXXX/DezaPata/contextSingleton.php:10
Stack trace:
#0 {main}
 thrown in /Users/XXXXX/DezaPata/contextSingleton.php on line 10

 

 

contextSingleton.php ←コンテキスト(使う側)

<?php

use DP\Singleton\Singleton;

echo "getInstanceしてみる(instance1)\n";
$instance1 = Singleton::getInstance();
echo "もう一度、getInstanceしてみる(instance2)\n";
$instance2 = Singleton::getInstance();
echo "2回目のgetInstanceはインスタンス生成を行わないため、constructを通らないはず\n";
echo "(instance1 === instance2)なのか確認\n";
echo ($instance1 === $instance2) . "\n";

$ php contextSingleton.php

getInstanceしてみる(instance1)
create SingletonClassInstance
もう一度、getInstanceしてみる(instance2)
2回目のgetInstanceはインスタンス生成を行わないため、constructを通らないはず
(instance1 === instance2)なのか確認
1

Singletonクラスのインスタンスを得ることができるgetInsranceメソッドを
2回実行してみる。
1回目でインスタンス生成によりコンストラクラにて初期化でいを行い、
2回目はインスタンス生成していないことがわかる。
さらに、1回目と2回目のインスタンスは同じであることもわかる。

→ Singletonクラスは1つしか存在せず、
getInstanceで毎回同じSingletonクラスのインスタンスを得ることができました!!!

 

<<追記 2019-03-12>>

ただし、このままの方法ではタッチの差で、

if (is_null(self::$singleton))

判定をした場合には
インスタンスが1つ以上作られる可能性があります。

この対策としては二つがあります。
●同期化
●初期化時点でインスタンスを生成し、
getInstanceでは常にそのインスタンスを返すようにする。

class Singleton
{
    private static $singleton = new Singleton();

    private function __construct()
    {
        echo "create SingletonClassInstance\n";
    }

    public static function getInstance()
    {
        return self::$singleton;
    }
}

 

 

static宣言

HogeClass.php

class HogeClass
{
    public static $staticProperty = "staticなプロパティです。\n";

    public static function staticMethod()
    {
        return "staticなメソッドです。\n";
    }
}

 

staticなメソッド、staticなプロパティともに
インスタンス化せずとも外部からアクセスが可能である。

echo HogeClass::$staticProperty;  //staticなプロパティです。
echo HogeClass::staticMethod();   //staticなメソッドです。

 

HogeClass内からのアクセスもself::で行う。
$this->で行うと、エラーとなる。

PHP Fatal error: Uncaught Error: Using $this when not in object context in

 

※注意!

staticなプロパティはインスタンス化されたクラスオブジェクトから
アクセスすることはできない(static なメソッドにはアクセスできます)。

$HogeObj = new HogeClass;
echo $HogeObj->staticProperty;
//PHP Notice:  Accessing static property HogeClass::$staticProperty as non static in...
echo $HogeObj->staticMethod();   //staticなメソッドです。

 

 

イテレーターを(iterator)を使ってみる

 

今回は、ご存知デザパタの
第1章 Iterator 〜1つ1つ数えあげる〜
について自分なりにまとめたいと思います。

 

イテレーター(iterator)とは

何かの集合体を、数える人
→ 何かの集合体(=aggregate)つまり数える対象が必要
→ 何かの集合体(=aggregate)がいてこその役に立つ

参考:
PHPで書き換えてくれてるソース
https://github.com/HappyDays-jQuery/GoF/tree/master/src/Iterator

 

※PHPでは組み込みで複数のインターフェースがあるので便利!
Iteratorインターフェース
IteratorAggregateインターフェース ..など

何かの集合体(aggregate)と、それを数える人(iterator)を別クラスにすることで、
役割分担ができ、疎結合になる。
→ ただし、aggregateとiteratorを別にする必要がない場合は、
両方の役割をもつIteratorAggregateを使うこともできる。

 

こんな感じ

全体コード→https://github.com/kin29/DezaPata/pull/2/files

– Bookクラス
– BookShelfクラス(=aggregate)
– BookShelfIteratorクラス(=iterator)
– コンテキスト(使う側)

BookShelf(集合体)の中にBook(要素)があり、
BookShelfIteratorが本を一つ一つ数えていく感じです。

BookShelfクラス

<?php

/**
 * 何か(=本)の集合体[Aggregate]
 */
class BookShelf
{
....
    public function getIterator(): BookShelfIterator
    {
        return new BookShelfIterator($this);
    }
}

コンテキスト(使う側)

<?php 

$bookShelf = new BookShelf();
$bookShelf->appendBook(new Book('星の王子様'));
$bookShelf->appendBook(new Book('かいけつゾロリ'));
$bookShelf->appendBook(new Book('ミッケ!'));
$bookShelfIt = $bookShelf->getIterator();

while ($bookShelfIt->hasNext())
{
    echo $bookShelfIt->next()->getName() . "\n";
}

実行すると、appendした本の名前が入れた順番に1つずつ表示されます。

$ php contextIterator.php
星の王子様
かいけつゾロリ
ミッケ!

 

イテレータのいいところ

何かの集合体(=aggregate)や数え方(=iterator)を変更しても、
イテレータを使う側には変更の必要がない。

例)
変更前:数え方→集合体へ要素を追加した順番(FIFO)
変更前:数え方→集合体へ要素を追加した逆の順番(FILO)

<?php 

namespace DP\Iterator; 

/**
 * 何か(=本)の集合体を数える人[Iterator]
 *
 * Class BookShelfIterator
 * @package DP\Iterator
 */ 

class BookShelfIterator {

    private $bookShelf;
    private $index;
  
    public function __construct(BookShelf $bookShelf)
    { 
        $this->bookShelf = $bookShelf;
-       $this->index = 0;
+       $this->index = $this->bookShelf->getLength() - 1;
    }

    public function hasNext(): bool
    {
-       return $this->index < $this->bookShelf->getLength();
+       return $this->index >= 0;
    }

    public function next(): Book
    {
        $book = $this->bookShelf->getBookAt($this->index);
-       $this->index++;
+       $this->index--;
        return $book;
    }
}

実行結果

$ php contextIterator_FILO.php
ミッケ!
かいけつゾロリ
星の王子様

 

イテレータ、便利だしスマートですね!

しかし未だ、これイテレータパターン使えるっ
って言う場面に直面したことがないので、
何か集合体を見つけては、ソースに落とし込むとかして
そういう直感を養っていこうと思います。

デザインパターン入門を読み始めました。〜GoFとは〜

 

有名なやつですね。

存在はもちろん知っていましたが、
難しそうという思い込みで読んでいませんでした。

読まなくては!といういい機会をいただき読み始めました。
入門なのもあり、Javaを知らない私でも意外に読める感じでした!
(思い込みはだめですね。)

 

PHPerな方が、この本と一緒によむといいのが、
デザパタをPHPで書いてくれてるやつ → HappyDays-jQuery/GoF

 

今回は、この本の導入部分のまとめを
自分なりに書いていきたいと思います。

 

GoF(ゴフ)とは

\「GoF」ってよく聞くけど、なんですか?/
という、私の初歩的な疑問がありました。
「はじめに」部分に詳しく書いてくれてました。

開発する上でのよくあるパターンを「デザインパターン」という形で整理したのが、
GoF(ゴフ)と呼ばれた4人だそうです。※GoF = the Gang of Fourの略

もっと詳しく言うと、このGoFにより
オブジェクト指向における再利用のためのデザインパターン
という本がかかれました。
この本では、23個のデザインパターンに「名前」をつけ、
「カタログ」としてまとめられています。

 

–まとめ–
GoF(ゴフ)とは、
デザインパターンを整理してくれた4人の人たちの名称。

 

デザインパターンを学ぶ前に

デザインパターンとは、クラスやインターフェースの関係性である。

デザインパターンの目的は、プログラムを再利用可能なものにすること。
→プログラムを部品として再利用すること
→プログラムを常に、機能拡張や変更を加えていくものとして見る必要がある。

なので、デザインパターンの理解を深めるためには以下を考えると良い。
・どんな機能が拡張される可能性があるか
・その拡張が行われると、修正が必要になるクラスはどれか
・逆に、修正が不要なクラスはどれか

 

また、役割を理解する必要がある。
この本では、デザインパターンをドラマに例えて整理しています。

– 白雪姫(というドラマ) … デザインパターン
– 白雪姫(登場人物) … クラスA
– 王子様(登場人物) … クラスB

白雪姫には、りんごを食べて永遠の眠りについてしまうという役目があるように、
クラスAは役割がある。
また、王子様には、白雪姫にキスをして目覚めさせるという役目があるように、
クラスBには役割がある。
白雪姫が眠らなければ王子様も役目を果たせないように、
し役割をまっとうする必要がある。
登場人物全員が役割を果たしてドラマができあがるように、
デザインパターンもできるという感じでしょうか。

 

次は、第1章Iteratorについてまとめたいと思います!

 

PHP7.3からbreakの代わりにcontinueを使うとWarningになる。

最近PHP7.3にしました!
すると、以下のエラーで大好きなcomposerが使えなくなりました。

 "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"?  

Google翻訳さんを使って、
「continue」ターゲティングスイッチは「break」と同じです。 “continue 2″を使用するつもりでしたか?
的なことをいってるみたいだなとわかりました。

 

( 解決策はQiitaに書いてます! )

composer installができなくなった時の解決法(PHP7.3)

 

 

そこでまず、
▶︎PHP7.3から、continueをbreakの代わりに使うと、Warningになる?
▶︎continue 2とは?使ったことない!
と私は直感で思いました。

 

 

よくわからなかったので、

とりあえず、やってみます。

参考:https://blog.ohgaki.net/php-7-3#continue

$ php -v
PHP 7.3.1 (cli) (built: Jan 10 2019 13:15:37) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.1, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.1, Copyright (c) 1999-2018, by Zend Technologies

 

test_continue.php

<?php
//$month = 1;を想定

for ($day = 1; $day <= 31; $day++) {

    $message = "{$day}日は、";
    switch ($day) {
        case 1:
            $message .= "月初\n";
            continue;  //break;と同じらしい
        case 15:
            $message .= "月のど真ん中\n";
            continue;
        case 31:
            $message .= "月末\n";
            continue;
        default:
            $message .= "なんともいえない日\n";
            continue;
    }

    echo $message;
}

 

いざ、実行!

$ php test_continue.php 
PHP Warning:  "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /Users/kin29/php7_3/test_continue.php on line 11
...
/Users/kin29/php7_3/test_continue.php on line 14
...
/Users/kin29/php7_3/test_continue.php on line 17
...
/Users/kin29/php7_3/test_continue.php on line 20
1日は、月初
2日は、なんともいえない日
...
15日は、月のど真ん中
16日は、なんともいえない日
...
31日は、月末

やはり、warningでてますねえ。
おっしゃる通りにcontinue→breakにしてみる。

test_break.php

<?php

//$month = 1;を想定

for ($day = 1; $day <= 31; $day++) {

    $message = "{$day}日は、";
    switch ($day) {
        case 1:
            $message .= "月初\n";
            break;  //continue;と同じ動作をするはず
        case 15:
            $message .= "月のど真ん中\n";
            break;
        case 31:
            $message .= "月末\n";
            break;
        default:
            $message .= "なんともいえない日\n";
            break;
    }

    echo $message;
}

breakで実行すると、
warningも出ず、continueの時と同じ挙動のようです!!!

$ php test_break.php 
1日は、月初
2日は、なんともいえない日
...
15日は、月のど真ん中
16日は、なんともいえない日
...
31日は、月末

そもそも、switchには普段からbreak使ってます。
なんとなくcontinueを使わず、break使ってましたが、それが正しいようです。

ではcontinueの使い時は?continue 2とは?
の確信につきたいと思います。

 

test_continue_2.php

<?php 

//$month = 1;を想定

for ($day = 1; $day <= 31; $day++) {

    $message = "{$day}日は、";
    switch ($day) {
        case 1:
            $message .= "月初\n";
            break;
        case 15:
            $message .= "月のど真ん中\n";
            break;
        case 31:
            $message .= "月末\n";
            break;
        default:
            $message .= "なんともいえない日\n";
            continue 2; //抜けるループのレベル指定
    }

    echo $message;
}

 

さっそく実行!

$ php test_continue_2.php 
1日は、月初
15日は、月のど真ん中
31日は、月末

continueに引数を使うと、抜けるループレベルが指定できるようです。
今回の例でいくと、breakやcontinue(引数なし)ではswitch文しか抜けません。
ただし、continue 2(引数あり)とするとfor文からも抜けだすことができます。

 

まとめ

breakとcontinue(引数なし)は同じ意味なのに、別で存在しているので統一させたい。
あんど、continueは引数ありで使うべきと言いたいんでしょうか。
(そう私は解釈しました。)

短縮URL取得ボタンを記事編集画面に設置する。

 

わたし、ブログ書いたらTwitterに書いたよーって
宣伝してるんですが、その時のURLが長くてきもいって
言われたり思ってたりしてたので、
短縮URL取得ボタンを記事編集画面に設置しました。

なのでこの度、
\短縮URLをTwitterに貼れるようになりました!/

 

参考:https://tamore.net/add-shorturl-button/

 

before

 

after:パーマリンク横に「短縮URL取得」ボタンが追加されました!

 

●やり方

wp-content/themes/twentyfifteen/functions.php

の終了行に以下を追記するだけです!
わたしの場合、使用していたテーマがTwentyFiftyなのでtwentyfifteen/以下のfunction.phpをいじります。
ご使用のテーマに合わせてください。

/**
 * 「短縮 URL を取得」ボタンを編集画面に表示させる
 */
add_filter( 'get_shortlink', function( $shortlink ) {return $shortlink;});

 

wp-admin/edit-form-advanced.phpを見てみると、
「短縮URLの取得」ボタンはデフォルトで隠してるみたいですね。

wp-admin/edit-form-advanced.php

// As of 4.4, the Get Shortlink button is hidden by default.
if ( has_filter( 'pre_get_shortlink' ) 
    || has_filter( 'get_shortlink' ) ) {
   $shortlink = wp_get_shortlink($post->ID, 'post');

   if ( !empty( $shortlink ) 
        && $shortlink !== $permalink 
        && $permalink !== home_url('?page_id=' . $post->ID) ) {
      $sample_permalink_html .= '<input id="shortlink" type="hidden" value="' 
            . esc_attr( $shortlink ) 
            . '" /><button type="button" class="button button-small" onclick="prompt(&#39;URL:&#39;, jQuery(\'#shortlink\').val());">' 
            . __( 'Get Shortlink' )
            . '</button>';
   }
}

 

 

●感想

こんな簡単だったのかとびっくりしました。

ただ、Twitterカードの表示確認ツール「Card validator」で確認してみると、

WARMでてる・・・見逃していいやつですか・・・?

slackコマンドを作ってみた!

どうも、今週は#Webナイト宮崎でLTしてきました!
そのLTの内容を書きます!

にしても、connpassのプロフィールにLTする人の一覧がありますが、
自分のアイコン画像(Facebookの)が高校の時の写真なので
そろそろ変えないとですね

 

本題に入ります!

今回は、heroku(+SendGrid) +  PHP + slack
でslackコマンドを作ってみました。
ソースはこちら→[kin29/slack_command]

 

こんなslackコマンド

slackの投稿エリアにて、

/(設定したcommand) [メール件名]|[メール内容]

と入力し、エンターを押すと、

1. herokuサーバにキックされる。
2. herokuのadd-onであるSendGridから、メールを送信する。
送信先:WordPressメール投稿機能(プラグインPostie)で設定されたメールアドレス
2′. WordPress(ブログ)に記事が下書きの状態で投稿される。
3.メール送信結果を、slackに投稿する、

 

使ったもの

– Slack

– heroku
今回はPHP 7.2.12を使用しました。

– SendGrid…メール機能が使えるherokuのadd-onです。
freeプランがあり、最大12,000通/月送信することができます。
※herokuはデフォルトでメール機能が使えません。

 

作った理由

私はブログを週1は更新する!という目標があります。
そこで、ブログ(kin29.info)のネタを
忘れないうちに、サクッと貯めておきたかったので作りました。

slackで技術的なお話をしてる時や、
レビューの返しなどをもらった時に
「これ使える!」ってネタが思くので、
その時に使いどきかなって思います!

 

作り方

ソースはこちら→[kin29/slack_command]

 

1.heroku経由でSendGridを導入する。

  • herokuダッシュボードよりCreate new appを押下し、
    プロジェクトを作成します。
    プロジェクト名がサブドメインになります。
    イメージ:https://[プロジェクト名].herokuapp.com/
  • herokuダッシュボード > Resources > Add-onsにて、
    「SendGrid」を検索し導入する。
    Starter – Free(送信通数上限12,000通/月)を選択し、
    Provisionを選択。
  • SendGridダッシュボード > 左ナビのSettings > API Keys より
    「Create API Key」を押下する。
    ※API Keyはコピーしておく。

 

2.slack app を新規作成する。

https://api.slack.com/apps より、Create New Appを押下する。

  1. AppName と 導入するSlack Workspaceを選択する。
    ※Verification Tokenをコピーしておく。
  2. Slash Commands の設定
    – Command :設定したいslack コマンド
    – Request URL :commandが投稿された時に実行されるURL
  3. Install Appより、「Install App to Workspace」を押下する。
    → Incoming Webhookが設定されます。
    メール送信結果を投稿するslackチャンネルを選択し、
    投稿をAuthorize(許可)する。
    ※Webhook URL をコピーしておく。

 

3.heroku でデプロイ

  1. コードを書く → [kin29/slack_command]
  2. herokuダッシュボード > Setting > Config Varsより
    環境変数を設定する。
  3. herokuダッシュボード > Deploy よりデプロイする。
    Heroku Git(Githubでもできます。)
    $ git push heroku master  //これでデプロイされます。
  4.  

    4.Postie(WordPressプラグイン)を導入し、メール投稿設定をする

    Postieは、WordPressのプラグインです。
    これにより、メール投稿を使って
    Wordpressに記事を投稿することができます。

    参考:http://nb-style.info/?p=3072

     

    !!完成!!

     

    最後に

    もっともっとslackコマンドつくって、
    作業時短化や自動化していきたいです!

.envから変数を取得するには、phpdotenvが必要である。

 

.envファイルの内容ってgetenv()で取得すると思うんですが、

それって、環境変数を取得するように、

何もライブラリとか入れずに取得できると思ってました。

 

答え

デフォルト状態で、getenv()より取得できる環境変数は

phpinfo()ででる $_ENV['XXX'] だけみたい。

.envファイルで設定した変数を取得するには、

phpdotenvを使う必要がある。

 

 

■デフォルト状態

$ cat .env
TOKEN=token_123
$ vi get_env.php 
<?php

var_dump('PATH: ' . getenv('PATH'));  
//"PATH: /Users/XXXXXX/.pyenv/shims:/usr/local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"

var_dump('TOKEN: ' .getenv('TOKEN'));  
//"TOKEN: " 取得できない(X_X)

 

 

■ phpdotenv導入後

$ composer require vlucas/phpdotenv
$ vi get_env.php
<?php
var_dump('PATH: ' . getenv('PATH'));  
//"PATH: /Users/XXXXXX/.pyenv/shims:/usr/local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" 

var_dump('TOKEN: ' .getenv('TOKEN'));  
//"TOKEN: token_123"  取得できた\(^^)/

JP_Stripes (Stripe ユーザーグループ)in 宮崎 Vol.2〜初登壇の反省付き〜

どうも!
先日、JP_Stripes (Stripe ユーザーグループ)in 宮崎 Vol.2
に行ってきました!
そこで、今回、初社外LTしてきました!\(^^)/
宮崎での開催は2回目ということでした。(1回目も参加してます)

 

黒レアらしいです!やったー

 

まずはじめに、
Stripe Japanの小島さんより、Stripeの概要説明がありました。

前回も概要説明はありましたが、内容が新しくなっていて聞き応えがありました。
わたしが気になったトピックは以下2点です。

<Stripe導入事例>
Cansell
行けなくなったホテル予約を売ったり、買ったりできるサービスらしく、
個人的にぜひ使ってみたいサービスだと思いました!
このサービスにもStripeが使われているとのことです。

SaaSを海外展開するために準備した3つのこと
Stripeを使った海外販売を通しての海外展開の大変さだったりを
詳細にまとめてくださってました。

<新機能!>
Isuuing  …APIでカードを作成
Terminal  …プラグラミング可能POS
Stripe + Twillio<pay> …シニアには良さそう

 

 

 

次に、quote 黒葛原 道さんより
「WordPress+WooCommerce+Stripeで作ってみてわかった、
簡単にECサイトを作る方法」

と題して、実際のオンラインショップquoteでStripeを導入したお話でした。
黒葛原さんは、デザイナーさんです。
購入フローふくめサイトの世界観も大事にしており、
Stripeだとそれを実現することができたようです。

\ 簡単に購入できる仕組みが欲しい /
運営側の、現場の、生の、お話が聞けて刺激になりました。

また、WPの開発ツールで、getflywheelというサービスがあるらしく、
わたしは知らなかったので、勉強になりました!

さらに、Stripeはクレカだけでなく、
ApplePayの決済対応も可能です。
そこで、ApplePayの

日本では、VISA カードは App 内や Web での支払いには使えません。

というこの仕様には初耳で、いい情報知れたなと思いましたー!
※店頭での支払いには対応してるらしいです。
参考: https://support.apple.com/ja-jp/HT201239

 

 

2番手で、私のLTでした。
「簡単決済「stripe」を導入してみる。」
という題名で、stripeのクイックスタートよりテストしてみた
の手順をまとめて、最後にデモしました^^
社外LTが初めてだったので、緊張しました。。。
詳しくは、Stripe決済をフレームワーク使わずに組み込んでみる!(PHP)
にまとめています。

<反省点>
– 自己紹介にインパクトが足らなかった。
– 声出し練習不足。
– 伝えたいことが、明確に出てなかった・まとめきれてなかった。
– 緊張で楽しめてなかった。次はもっと楽しみたい。

初LTということで、場数不足は当たり前に痛感しました。
これから、さらに経験値積んでいきたいと思います。
貴重な機会を提供してくださってありがとうございました!

 

 

最後に、イラスティックコンサルタンツ株式会社
緒方 宣行さん、野島 隆さんより
「もっと自由で柔軟に構築しよう!
Stripre決済にも対応した新しいカートシステム」
と題して、 Stripeを使ったAPIサービスのお話でした。

PHPとVue.jsを使ったサービスでした。
技術者の方が、
PHPerでPhpStorm使いというだけで共感わいちゃいました。

Stripeを使っての、
フロント側のデザイン自由度の高いサービスを作ることができる事例でした。
いろんなビジネスの可能性を感じました。

 

 

Stripeはじめキャッシュレスは安倍さんが擁護してるだけあって、
今後さらに注目していきたいなと思います!

JP_Stripesに参加すると毎回思うのですが、
ビジネスアイデアが沸けば、Stripeを使うことで一攫千金も夢じゃないなあ
っとしみじみ感じます。#JP_Stripes

 

stripe決済をフレームワーク使わずに組み込んでみる!(PHP)

こんにちは!
過去に簡単決済「stripe」を導入してみる。を紹介しました。
今更気づいたんですが、べつにLaravel使う必要なかったなって(笑)
ただ、使いたかったんだと思います!ww

そこで!
PHPのフレームワークを使わないパターンで
もっとシンプルに組み込みたいと思います。

完成は、こちらです。
[ kin29/stripe_practice_php ]
↑だと、.envの設定だけで
ビルドインサーバ立てたら、もうできちゃいます。

 

さあ、つくろう。

リファレンス

stripe API
Card Payments Quickstart
ほぼ、↑のクイックスタートをやってます。

環境

– Mac
– PHP7.2.7

準備

stripeアカウント発行、テスト環境申請(申請後すぐできました)
↑これだけ!

手順

1.プロジェクト(作業ディレクトリ)の作成

~$ mkdir stripe_practice_php/

 

2.stripe/stripe-phpの導入 ←composer経由

$ cd stripe_practice_php/
$ composer require stripe/stripe-php
You are running composer with xdebug enabled. This has a major impact on runtime performance. See https://getcomposer.org/xdebug
Using version ^6.20 for stripe/stripe-php
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing stripe/stripe-php (v6.20.0)
    Downloading: 100%
Writing lock file
Generating autoload files

$ ls
composer.json composer.lock vendor

 

3.カード情報入力フォームをつくる。

$ cd stripe_practice_php/
$ vi index.php
...
<div class="content">  
  <div class="title">stripe DE おかいもの</div>
  <div>¥100</div>
    <form action="./payment.php" method="POST">
    <script
       src="https://checkout.stripe.com/checkout.js"
       class="stripe-button"
       data-key="{pk_test_XXXXXXXXXXXXXXXXXXX}"
       data-amount="{商品の値段}"
       data-name="{カード入力モーダルのタイトル}"
       data-description="{カード入力モーダルのタイトル下の説明文}"
       data-image="https://stripe.com/img/documentation/checkout/marketplace.png"
       data-locale="auto"
       data-currency="jpy">
    </script>
  </form>
</div>
...

 

 

4.バックエンドをつくる。

$ cd stripe_practice_php/
$ vi payment.php
<?php
require __DIR__.'/vendor/autoload.php';

\Stripe\Stripe::setApiKey("{sk_test_XXXXXX}"); 

$token = $_POST['stripeToken']; //ここでAPIにリクエストしてる
   
$charge = \Stripe\Charge::create([
    'amount' => 100,
    'currency' => 'jpy',  //usd(ドル)→jpy(円)に変更しました。
    'description' => 'Example charge',
    'source' => $token,
]);
    
//thanks.phpにリダイレクトさせる。
header("Location: ./thanks.php");

 

5.サンクスページをつくる。

$ cd stripe_practice_php/
$ vi thanks.php
...

<div class="content">
   <div class="title">「stripe DE おかいもの」<br>ご利用TEGEありがとうございました。</div>
   <div>利用金額:¥100</div>
  </form>
</div>

...

 

6.完成! →実際に動かしてみる「http://localhost:8080/index.php

$ cd stripe_practice_php/
$ php -S localhost:8080   //ビルドインサーバを立てる

※テスト用のカード番号の参考はこちら
https://stripe.com/docs/testing#cards

 

7.管理画面をみてみる。 →実際にみせちゃう
https://dashboard.stripe.com/test/dashboard

 

‘currency’ => jpy

に変更することにより、
円請求ができますが、管理画面ではドルに換算されていました。

 

まとめ

・簡単!早い!わかりやすい!

・ドキュメントは英語ですが、読みやすく充実してます。

・リンク型なので、面倒なトークン化(カード情報非保持)対応の必要なし!

・次は、PHP以外の言語でもしてみたいです!

Laravel環境構築してみる!

話題のこの本、
「PHPフレームワーク Laravel Webアプリケーション開発」読んでます!
まだ読み途中ですが・・・。
今回は最初の「環境構築」部分を自分なりにまとめたこと描きます。

Github

環境構築のパターン

  1. VagrantでLaravel環境構築
  2. DockerでLaravel環境構築

二つとも、Macでやります!

1. VagrantでLaravel環境構築

■事前準備
・VirtualBoxのインスートル
・Vagrantのインスートル

■構築する環境
・ドキュメントルート … /home/vagrant/code/testapp/public
・laravelプロジェクトdir … /home/vagrant/code/testapp
・共有dir … /home/vagrant/code = /home/(ユーザdir)/code

■手順

$ cd  /*(user_dir)に移動する*/

$ vagrant box add laravel/homestead

$ git clone git@github.com:laravel/homestead.git Homestead

$ cd Homestead/

# 初期化
$ sh ./init.sh

# ゲストOSの設定ファイル調整
$ vi Homestead.yaml  /* ip、sites、authorize、keyの設定 */

# hosts設定 「192.168.10.10 homestead.test」
$ vi /etc/host  /* Homestead.yamlに合わせてip設定する */

$ cd /*(user_dir)に移動する*/

# ゲストOSとホストOSの共有dir先を作成 
# /home/vagrant/code = /home/(ユーザdir)/code
$ mkdir code/

$ cd Homestead/

# 調整し直したHomestead.yamlの設定でvagrantで環境を立てる 
$ vagrant up

# sshでゲストOSに入る
$ vagrant ssh

# ここからゲストOSにいる
$ cd code/

$ composer create-project laravel/laravel testapp --prefer-dist "5.5.*"

http://homestead.test/
にアクセスするとlaravelのページにアクセスできることを確認!完成\(^^)/

■つまったところ
・何回も作りなお直してたら、もうあるってめちゃ言われました。(以下参照)

The box you're attempting to add already exists. Remove it before
adding it again or add it with the `--force` flag.

Name: laravel/homestead
Provider: virtualbox
Version: 6.3.0

そんなときの対処方法
・その壱

$ vagrant global-status /* 動いてるやつの確認 */
$ vagrant global-status --prune /* 何も出てこない時はこっち */
$ vagrant destroy homestead-7 /* 「homestead-7」を指定してdestroy */

・その弐

$ cd ~/.vagrant.d/boxes/
$ ll
$ rm -rf {target}

2. DockerでLaravel環境構築

■事前準備
・Dockerのインスートール

■構築する環境
・ドキュメントルート … /var/www/public
・laravelプロジェクトdir … /var/www/
・共有dir … /var/www = /home/(ユーザdir)/laravel_docker/testapp

■手順

$ cd

$ mkdir laravel_docker

$ cd laravel_docker

$ git clone https://github.com/laradock/laradock.git

$ cd laradock

$ cp env-example .env

# コンテナ起動(初期化)
$ docker-compose up -d nginx mysql workspace phpmyadmin

# 起動中のコンテナ一覧の確認。各コンテナが起動(up)していることを確認
$ docker-compose ps

# ゲストOSに入る
$ docker-compose exec --user=laradock workspace bash

# testappという名前でlaravelをいれる。
$ composer create-project laravel/laravel testapp --prefer-dist "5.5.*" 

# ゲストOSからでる。
$ exit

# laradock/.envの調整。「APP_CODE_PATH_HOST=../testapp」に書き換える
# /var/www = (user_dir)/laravel_docker/testapp にさせるために!
$ vi .env

# コンテナ一旦シャットダウン
$ docker-compose stop
 
# コンテナ起動。再起動により.envが反映されます。
$ docker-compose up -d nginx mysql

http://localhostでアクセスすると、
laravelのデフォ画面がでるはずです!完成^^

この本ですが
内容はとても親切丁寧なので読みやすいです!
ADRの話なども書いてあって、私には難しいですが頑張れそうです!
もっと読んだらまた記事書きまうす。