Ratchetを利用してPHPでWebソケット 1

PHP

一つの課題がありまして、PHPでもうすでにできあがっているプログラムがあり、でもWebsocketでリアルタイム通信をしたいという課題です。

弊社では、今までWebsocketでリアルタイム通信をするとき、node.jsをよく利用していました。
が、すでにあるプログラム群に追加するのはいろいろと面倒だったのです。

そこで、Ratchet WebSockets for PHPなるものがあることがわかりました。
http://socketo.me/

ほほー
これは、私が求めているものに近い!!
しかも、解説が親切!

というわけで、とりあえず、最初のチュートリアルからやってみます。

“hello world”やってみよう、という公式サイトを初心者目線で解説してみます。
http://socketo.me/docs/hello-world

とりあえず、例として、サーバーの下記のパスにratchetを入れてみます。

 /var/www/html/test/ratchet/

まず、PSR-0というライブラリとか、Ratchetのライブラリを入手します。
こういうのは、今時はもうcomposerでさくっとやっちゃうのです⊂(^-^)⊃

composerの例文がありますね。

 {
    "autoload": {
        "psr-0": {
            "MyApp": "src"
        }
    },
    "require": {
        "cboden/ratchet": "0.3.*"
    }
 }

ちなみに、PSR-0のサイトへ行くと、PSR-4を使ってくれよーん(2016年5月2日現在)と書いてあるので、気を利かしてpsr-4とやっても、ratchetさんのほうで対応していないので、動きません!

上記をテキストファイルに書いて、composer.jsonという名前でサーバーにアップロードします。

 $ composer update

とやります。

あとはですね、/var/www/html/test/ratchet/の中に、src/MyAppというディレクトリを作って、その中にChat.phpという名前で次のPHPファイルを保存します。

 <?php
 namespace MyApp;
 use Ratchet\MessageComponentInterface;
 use Ratchet\ConnectionInterface;
 
 class Chat implements MessageComponentInterface {
    protected $clients;
 
    public function __construct() {
        $this->clients = new \SplObjectStorage;
    }
 
    public function onOpen(ConnectionInterface $conn) {
        // Store the new connection to send messages to later
        $this->clients->attach($conn);
 
        echo "New connection! ({$conn->resourceId})\n";
    }
 
    public function onMessage(ConnectionInterface $from, $msg) {
        $numRecv = count($this->clients) - 1;
        echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
            , $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');
 
        foreach ($this->clients as $client) {
            if ($from !== $client) {
                // The sender is not the receiver, send to each client connected
                $client->send($msg);
            }
        }
    }
 
    public function onClose(ConnectionInterface $conn) {
        // The connection is closed, remove it, as we can no longer send it messages
        $this->clients->detach($conn);
 
         echo "Connection {$conn->resourceId} has disconnected\n";
    }
 
    public function onError(ConnectionInterface $conn, \Exception $e) {
         echo "An error has occurred: {$e->getMessage()}\n";
 
        $conn->close();
    }
 }

次に、/var/www/html/test/ratchet/の中に、binというディレクトリを作って、その中にchat-server.phpという名前で次のPHPファイルを保存します。

 <?php
 use Ratchet\Server\IoServer;
 use MyApp\Chat;
 
    require dirname(__DIR__) . '/vendor/autoload.php';
 
    $server = IoServer::factory(
        new Chat(),
        8080
    );
 
    $server->run();

サーバーで、次のようにやります。

 $ php bin/chat-server.php

Windowsで、コマンドプロンプトを立ち上げます。
hogehoge.netというサーバーに上記の設定をしたとすると、

 telnet hogehoge.net 8080

とやります。
ちなみに、デフォルトでWindows10にTelnetは無効化されてますので、下記の記事を参考に有効化してください。
Windows10 Telnetを使う

もう一つ、コマンドプロンプトを立ち上げます。

 telnet hogehoge.net 8080

とやります。

すると、一方の画面で文字を打つと…
もう一方の画面にでてくるんですね!!
すごい!
感動ひとしお!!!

  • aaaaa — bbbbb {2018-01-07 (日) 08:24:57}

PHP 連想配列の配列中に、特定の値がないか調べる

PHP

PHP 連想配列の配列中に、特定の値がないか調べる

配列の中にある値がないか調べるのはin_array でできますし、連想配列の中身を調べるのはforeachでも追加すればいいのですが、ちょっと面倒ですよね。

http://www.php.net/manual/ja/function.in-array.php

上記のサイトにあったサンプルコードが利用しやすかったので、メモがてら記録しておきます。。

 <?php
  //$needle は探したい値、$needle_fieldは探したいキーの名前、$haystackは探す配列
 function in_array_field($needle, $needle_field, $haystack, $strict = false) {
     if ($strict) {
        foreach ($haystack as $item)
            if (isset($item->$needle_field) && $item->$needle_field === $needle)
                return true;
    }
    else {
        foreach ($haystack as $item)
            if (isset($item->$needle_field) && $item->$needle_field == $needle)
                return true;
    }
    return false;
 }
 ?>

PHPUnit 超ことはじめ

PHP

私はAndroidアプリではJUnitを使って開発をしたことがありますが、PHPのユニットテストは初めてです。
PHPUnitをこれから勉強していきます。という超最初の一歩です。

PHPUnitの大変よい点は、日本語のマニュアルがしっかりしてる!ちゃんとある!ってことですね[smile]
https://phpunit.de/manual/current/ja/installation.html

ありがたやー ありがたやー

まずは、自分の開発用のWindowsPCに、上記のURLの記述に沿って、PHPUnitをインストールしてみます。

 phpunit --version

とかやってみて、バージョンが表示されるのを見て喜んでみます⊂(^-^)⊃

まず、簡単!なテストを作って、テストを走らせてみます。

 //テストする元のクラス
 //Calculator.php
 <?php
 class Calculator
 {
 
    public function add($a, $b)
    {
        return $a + $b;
    }
 
 }
 //テスト
 <?php
 require 'Calculator.php';
 
 class CalculatorTests extends PHPUnit_Framework_TestCase
 {
    private $calculator;
 
    protected function setUp()
    {
        $this->calculator = new Calculator();
    }
 
    protected function tearDown()
    {
        $this->calculator = NULL;
    }
 
    public function testAdd()
    {
        $result = $this->calculator->add(1, 2);
        $this->assertEquals(3, $result);
    }
 
 }

上記2つのファイルを下記のフォルダに入れます。
C:\xampp2\htdocs\test\php_unit

コマンドプロンプトで

 phpunit CalculatorTest.php

とやります。

 OK

と表示されましたね[smile]

PHP 2点間の直線距離を求める式

PHP

PHP 2点間の直線距離を求める式

以下の住所、2点間の直線距離を求めます。
出発地:神奈川県横浜市神奈川区鶴屋町2-21
目的地:東京都港区芝公園4-2

主なやりかたは、geocording化して、地球の半径やら緯度経度をラジアンにするなどを行って計測させます。

*geocordingはされているものとして考えます…。

出発地の緯度経度

 $start_latutude = 35.46943;
 $start_longitude = 139.621018;

目的地の緯度経度↓

 $end_latitude = 35.658604;
 $end_longitude = 139.745133;

地球の半径

 $earth_r = 6378.137;

緯度差・経度差をラジアンに

 $latitude_margin = deg2rad($end_latitude - $start_latutude);     
 $longitide_margin = deg2rad($end_longitude - $longitude );

南北の距離

 $south_north = $earth_r * $latitude_margin;

東西の距離

 $west_east = cos(deg2rad($start_latutude)) * $earth_r * $longitide_margin;

三平方の定理

 $distance = sqrt(pow($west_east,2) + pow($south_north,2));

ちなみに計算を行うと、23.808kmになりました!!

PHP 小数か整数かの正規表現

PHP

PHP 小数か整数かの正規表現

小数(0.5とか1.22とか)、あるいは整数(1とか10とか)で許可する場合です。

 if(! preg_match('/^[0-9]+(\.[0-9]*)?$/', $int_or_float)){
     echo "小数か整数を入力してください";		
 }