ラベル PHP の投稿を表示しています。 すべての投稿を表示
ラベル PHP の投稿を表示しています。 すべての投稿を表示

2018年3月19日月曜日

PHPUnit を Composer でインストールする。それだけ。

PHPUnit を初めてインストールしました。
あまりにも当たり前すぎて、ググった記事にはない内容もあるので記録しておきます。

前提

  • Windows 環境です(Unix/Mac 環境でもほぼ同じですが)

PHPUnit を Composer でインストール

インストール方法はいくつかありますが、composer を使います。

以下の composer.json を準備して、
{
    "require-dev": {
        "phpunit/phpunit": "7.0.*"
    }
}

インストール。
composer install

実行ファイルが以下の場所に出来ます(※これを探しました笑)
project_root/vendor/bin/phpunit.bat

project_root/vendor/bin/ に PATH を通して
(画像は RapidEE を使ってます)


Version 確認コマンドが働いたらインストール確認まで完了。
phpunit.bat --verion

Version 確認コマンドの実行結果。オッケー。
PS C:\Git\60_GitLab\sample_project> phpunit.bat --version
PHPUnit 5.0.10 by Sebastian Bergmann and contributors.

以上。

参考

https://phpunit.readthedocs.io/ja/latest/installation.html

2018年3月18日日曜日

Selenium + Chrome の環境が一瞬で構築できたというアレ。

前提

さて Selenium を試してみようか!
と思った時点で、こんな環境でした。
  • Windows10 64bit
  • Chrome はもちろんインストール済
  • php もインストール済
    • そしてパスが通っている
  • composer もインストール済
    • そしてパスが通っている

ブラウザのオートメーションと言えば昔は…

余談ですが、昔やったときは VB かなんかで IE を CreateObject して、なんか色々頑張ってやる感じで、まぁブラウザの操作自動化しても良いけどクソ面倒くさいよ。むしろ AutoHotKey とかでキー操作を自動化したほうが早いわ。ぐらいに思っていましたが…、時代は大分前進していたようで。

Selenium で Chrome を自在に動かす。しかも一瞬で。

さて、早速準備ですがやることはこれだけです。
  1. PHP 用ドライバを DL
  2. Windows 用 Chrome ドライバを DL

PHP 用ドライバを DL

composer.json にこう書いてインストールするだけです。
{
    "require": {
        "facebook/webdriver": "1.5.*"

    }
}
※最新版の Version は GitHub で確認してください

インストール。どん。
composer install
以上。

Windows 用 Chrome ドライバを DL

ここから「chromedriver_win32.zip」をダウンロードして解凍するだけです。
64bit 専用はないので、64bit でも 32bit 版で動かします。
linux と mac 版も置いてありありますね。
※最新版の Version はこちらで確認してください

Selenium の Hello world

ここまでできたら、あとはソースがあれば動きます。
試しに Google で Hello world を検索して見ます。

ソースはこんな感じ。

hello_world.php
<?php
require_once './vendor/autoload.php';

use Facebook\WebDriver\Chrome\ChromeDriver;
use Facebook\WebDriver\WebDriverExpectedCondition;
use Facebook\WebDriver\WebDriverBy;

function hello_world()
{
    // 環境変数にドライバパスを設定
    putenv('webdriver.chrome.driver=' . __DIR__ . '\chromedriver.exe');
    
    // Chrome を起動してページ遷移する
    $driver = ChromeDriver::start();
    $driver->get("https://www.google.co.jp/?q=helloworld");
    // 【検索】ボタンを押下
    $elem = $driver->findElement(WebDriverBy::name('btnK'));
    $elem->click();

    sleep(3);
    $driver->close();
}

hello_world();

※ facebook webdriver の API 一覧はこちら

最終的なフォルダ構成は、こうなっています。

あとはコレを実行すると、、
php hello_world.php

ブラウザが立ち上がり…

https://www.google.co.jp/?q=helloworld に遷移して【Google 検索】をクリックし…

検索結果のページが表示され…

3秒待機したら終了します。

はい、ここまで一瞬ですね。素晴らしい。
正直、こんなに簡単だとは思っていませんでした。

これで、ローカルでの自動化環境は整いました。
あとは API などを見ながら味付けしていく感じかと思います。
今回は、目的がローカル環境で達成できたので、 Selenium Server を使用していません。

次は、Selenium Server と組み合わせてみたいと思います。

以上。

補足

今回は facebook 製のを使いましたが、PHP の Web driver は公式では 3つ紹介されています。

参考

2018年3月10日土曜日

PHP のシステムから SendGrid を使ってみました。

メール送信機能を追加する機会があったのですが、サーバに何も設定されておらず、Dev や Staging など複数台のサーバに作業するのは面倒だなぁと。。
じゃぁ SendGrid を使って見ようということでやってみたら、驚くべき楽さで出来たという話です。。
  1. API KEY を取得する
  2. composer で library を install
  3. サンプルのママでメールが届く
正味30分もかかららず終わりました。。
サーバをアレアレ弄ってるとあっという間に1時間くらいたつので、ダンチです。
API 経由であれば、送信に失敗したときのエラーもしっかり返してくれるので、mail() や mb_send_mail() よりも優しい。。

API KEY を取得する

早速やった内容ですが、
API KEY は SendGrid の管理画面で取得します。
KEY 毎に細かく権限を設定できるようです。
【Create & View】を押下すると Key が表示されます。

こんな感じ。
1回きりしか表示されません。【Done】を押下するとその後は「*****」とマスクされた状態でしか見れません。忘れたら削除するのみ。

composer で library を install

GitHub repository の README にあるように、composer が使えるので composer.json に以下の記述をして、composer install するだけ。
{
  "require": {
    "sendgrid/sendgrid": "~6.0"
  }
}
https://github.com/sendgrid/sendgrid-php

サンプルのママでメールが届く

これも同 README にあるように書いて、API KEY と to のメアドだけ書き換えれるだけ。
// If you are using Composer (recommended)
require 'vendor/autoload.php';

// If you are not using Composer
// require("path/to/sendgrid-php/sendgrid-php.php");

$from = new SendGrid\Email("Example User", "test@example.com");
$subject = "Sending with SendGrid is Fun";
$to = new SendGrid\Email("Example User", "test@example.com");
$content = new SendGrid\Content("text/plain", "and easy to do anywhere, even with PHP");
$mail = new SendGrid\Mail($from, $subject, $to, $content);

$apiKey = getenv('SENDGRID_API_KEY');
$sg = new \SendGrid($apiKey);

$response = $sg->client->mail()->send()->post($mail);
echo $response->statusCode();
print_r($response->headers());
echo $response->body();
https://github.com/sendgrid/sendgrid-php

これだけで(躓きもなく)動きました。素敵ですね。
料金体系もやたら優しいので、わざわざメールの設定するぐらいならこっちのがいいやと感じました。
回し者ではありませんよ(笑
それでは。

2018年2月26日月曜日

Steam に OpenID で接続する

Steam Web API の続きです。

自分のアカウントで Sign in する機能を忘れていたので実装してみました。
↓こういうやつ
Steam には OpenID で接続します。
https://steamcommunity.com/dev

接続には、ここで紹介されていた LightOpenID を使います。

以前に作成した対戦履歴を表示するコードを、以下のように変更しました。

  • Steam ID をセッションから取得する
    • 無ければ Sign in させる
  • API Key を環境変数から取得する

session_start();
if (!isset($_SESSION['steam_id'])) {
 // Require sign in.
 echo "
 <div style='text-align:center'>
  <p><a href='/auth.php'><img src='http://steamcommunity-a.akamaihd.net/public/images/signinthroughsteam/sits_02.png' width='109' height='66' border='0'></a></p>
  <p>Please sign in.</p>
 </div>
 ";
} else {

 // https://gist.github.com/almirsarajcic/4664387
 function convert_steamid_64bit_to_32bit($id)
 {
  $result = substr($id, 3) - 61197960265728;
  return (string) $result;
 }
 function convert_steamid_32bit_to_64bit($id)
 {
  $result = '765'.($id + 61197960265728);
  return (string) $result;
 }

 $key = getenv("STEAM_API_KEY"); // Set API key from environment variable.
 $steamid = $_SESSION['steam_id']; // Set target's steam id here.
 echo "<h2>SteamID : {$steamid}</h2>";
 $accountid = convert_steamid_64bit_to_32bit($steamid);
 echo "<h2>accountid : {$accountid}</h2>";

 $curl = curl_init();
 
 // ヒーローリストを取得する
 curl_setopt($curl, CURLOPT_URL, "https://api.steampowered.com/IEconDOTA2_570/GetHeroes/v1?key={$key}");
 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
 $json = curl_exec($curl);
 $response = json_decode($json);
 $heroes = [];
 foreach ($response->result->heroes as $hero) {
  $heroes[$hero->id] = str_replace("npc_dota_hero_", "", $hero->name);
 }

 // 対戦履歴を取得する
 curl_setopt($curl, CURLOPT_URL, "https://api.steampowered.com/IDOTA2Match_570/GetMatchHistory/v1?key={$key}&account_id={$accountid}");
 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
 $json = curl_exec($curl);
 $response = json_decode($json);

 curl_close($curl);

 // 対戦履歴一覧を表示する
 foreach ($response->result->matches as $match) {
  $start_time = new DateTime('@' . $match->start_time);
  foreach ($match->players as $player) {
   if ($player->account_id == $accountid) {
    $hero_name = $heroes[$player->hero_id];
    $img = "<img src='http://cdn.dota2.com/apps/dota2/images/heroes/{$hero_name}_sb.png'>";
   }
  }

  echo "
  <div>
  {$start_time->format('Y/m/d H:i:s')}
  {$img}
  </div>
  ";
 }

}
index.php

Sign in は別のファイルで実装しました。
<?php
include_once("../vendor/autoload.php");

$openid = new LightOpenID("https://test-steam-web-api.azurewebsites.net");
$openid->identity = "http://steamcommunity.com/openid";
$openid->returnUrl = "https://test-steam-web-api.azurewebsites.net/auth.php";

if (!$openid->mode) {
 header('Location: ' . $openid->authUrl());
} elseif ($openid->mode == 'cancel') {
 header('Location: /');
} else {
 if ($openid->validate()) {
  session_start();

  $claimed = explode("http://steamcommunity.com/openid/id/", $openid->identity);
  $steam_id = $claimed[1];
  $_SESSION['steam_id'] = $steam_id;
 }

 header('Location: /');
}

exit;
auth.php

実際に動かせるサイトを準備しました。
コードはこちら

参考

https://steamcommunity.com/dev
https://github.com/iignatov/LightOpenID/blob/master/examples/example.php

2018年2月25日日曜日

Steam Web API で Dota2 の対戦履歴を表示する

Steam Web API の続きです。
自分の Dota2 の対戦履歴を取得するところまでやってみました。

使う API は以下の2つ。
あと、画像を取得するのに CDN を利用します。
  • http://cdn.dota2.com/apps/dota2/images/heroes/<name>_<suffix>
CDN の使い方はこちらに書いてありますが、1例を。
http://cdn.dota2.com/apps/dota2/images/heroes/pangolier_lg.png

これらを組み合わせて、対戦履歴を表示してみました。
コードはこんな感じに。


 // https://gist.github.com/almirsarajcic/4664387
 function convert_steamid_64bit_to_32bit($id)
 {
  $result = substr($id, 3) - 61197960265728;
  return (string) $result;
 }
 function convert_steamid_32bit_to_64bit($id)
 {
  $result = '765'.($id + 61197960265728);
  return (string) $result;
 }

 $key = "YOUR_API_KEY"; // Set Your API key here.
 $steamid = 76561197961028586; // Set target's steam id here.
 echo "<h2>SteamID : {$steamid}</h2>";
 $accountid = convert_steamid_64bit_to_32bit($steamid);
 echo "<h2>accountid : {$accountid}</h2>";

 $curl = curl_init();
 
 // ヒーローリストを取得する
 curl_setopt($curl, CURLOPT_URL, "https://api.steampowered.com/IEconDOTA2_570/GetHeroes/v1?key={$key}");
 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
 $json = curl_exec($curl);
 $response = json_decode($json);
 $heroes = [];
 foreach ($response->result->heroes as $hero) {
  $heroes[$hero->id] = str_replace("npc_dota_hero_", "", $hero->name);
 }

 // 対戦履歴を取得する
 curl_setopt($curl, CURLOPT_URL, "https://api.steampowered.com/IDOTA2Match_570/GetMatchHistory/v1?key={$key}&account_id={$accountid}");
 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
 $json = curl_exec($curl);
 $response = json_decode($json);

 curl_close($curl);

 // 対戦履歴一覧を表示する
 foreach ($response->result->matches as $match) {
  $start_time = new DateTime('@' . $match->start_time);
  foreach ($match->players as $player) {
   if ($player->account_id == $accountid) {
    $hero_name = $heroes[$player->hero_id];
    $img = "<img src='http://cdn.dota2.com/apps/dota2/images/heroes/{$hero_name}_sb.png'>";
   }
  }

  echo "
  <div>
  {$start_time->format('Y/m/d H:i:s')}
  {$img}
  </div>
  ";
 }
https://github.com/jtanaka/test_steam_web_api

実行するとこんな感じに。



無事表示することができました。
ここまで確認できればサービス作れますね。

参考

https://wiki.teamfortress.com/wiki/WebAPI#Dota_2

2018年2月20日火曜日

Steam Web API で求められる account_id とは

Steam Web API の一覧をみていると、必須 paramter に account_id というのが結構でてきます。



これは Steam ID でも API KEY でもないのですが、パッと探しても情報がでてきずらいのでメモしておきます。

account_id とは

「32-bit account ID」 とか 「STEAMID32」とか呼ばれていますが、要するに
  • STEAM ID が 64-bit の ID
  • STEAM ID の 32-bit 版 が account_id
ということです。

生成方法

で、その STEAMID64 と STEAM32 を相互変換する式があって、その方法がこちら。
  • STEAMID64 - 76561197960265728 = STEAMID32
  • STEAMID32 + 76561197960265728 = STEAMID64
  • OR
  • STEAMID32 = The right-most 32-bits of STEAMID64
  • STEAMID64 = concatenate("00000001000100000000000000000001", STEAMID32);
出典: https://dev.dota2.com/showthread.php?t=58317
上記は、64-bit の数値を扱える場合。
そうでない場合は、もうちょっと頑張る必要があるとのこと(試していません)。
define("STEAM_ID_UPPER_32_BITS", "00000001000100000000000000000001");
    // gets the lower 32-bits of a 64-bit steam id
    function GET_32_BIT ($ID_64) {
        $upper = gmp_mul( bindec(STEAM_ID_UPPER_32_BITS) , "4294967296" );
        return gmp_strval(gmp_sub($ID_64,$upper));
    }

    // creates a 64-bit steam id from the lower 32-bits
    function MAKE_64_BIT ( $ID_32, $hi = false ) {
        if ($hi === false) {
            $hi = bindec(STEAM_ID_UPPER_32_BITS);
        }

        // workaround signed/unsigned braindamage on x32
        $hi = sprintf ( "%u", $hi );
        $ID_32 = sprintf ( "%u", $ID_32 );

        return gmp_strval ( gmp_add ( gmp_mul ( $hi, "4294967296" ), $ID_32 ) );      
    }  
※出典: https://dev.dota2.com/showthread.php?t=47115&page=27&p=312817&viewfull=1#post312817

GitHub に相互変換のソースもありました。
https://gist.github.com/almirsarajcic/4664387

以上。

2018年2月19日月曜日

Steam に Web API があったので試してみた

Dota 2 をやっていると、何か自分の対戦履歴が自動で反映されている Web サイトがあったりするわけです(超便利)。
https://www.dotabuff.com

気になったので調べてみたら、やはり Web API があるようで。
https://wiki.teamfortress.com/wiki/WebAPI#Dota_2

試してみました。

API Key を取得する

ここで、API Key を取得します。

取得するとキーの所にキーが表示されます。
ドメイン名は、公開予定も無いのでとりあえず適当で大丈夫でした。

自分のプロフィールを取得してみる

手始めに、プロフィールを取得してみます。

        $key = "YOUR_KEY";
        $steamid = "76561197961028586";

        $curl = curl_init("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key={$key}&steamids={$steamid}");
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $response = curl_exec($curl);

        var_dump($response);
        curl_close($curl);
こんな感じに出力されます。

{
  "response": {
    "players": [
      {
        "steamid": "76561197961028586",
        "communityvisibilitystate": 3,
        "profilestate": 1,
        "personaname": "TANAKA",
        "lastlogoff": 1518968667,
        "profileurl": "http://steamcommunity.com/id/jumtana/",
        "avatar": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/bd/bd0af6bb099845e0c93d3bba467cdd96e743ce51.jpg",
        "avatarmedium": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/bd/bd0af6bb099845e0c93d3bba467cdd96e743ce51_medium.jpg",
        "avatarfull": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/bd/bd0af6bb099845e0c93d3bba467cdd96e743ce51_full.jpg",
        "personastate": 1,
        "realname": "Jumpei Tanaka",
        "primaryclanid": "103582791429548415",
        "timecreated": 1063939457,
        "personastateflags": 0,
        "loccountrycode": "JP",
        "locstatecode": "40",
        "loccityid": 26138
      }
    ]
  }
}
取れてる取れてる。
単純に上記だけであれば、GET なのでブラウザでも見れます。

次は対戦履歴でも取得してみます。