エントリー

カテゴリー「制作」の検索結果は以下のとおりです。

Android版GPUImageで画像加工

画像や動画にエフェクトをかけることができるライブラリである、GPUImageをAndroidから使ってみたのでメモ。

サンプル実行

NDK(Android Native Development Kit)のインストールが必要

GradleでNDKを自動インストールしてくれるプロジェクトもあるが、GPUImage for Android のサンプルはそうなっていない。Android Studio で

ファイル → 設定 → SDK Tools → NDK

にチェックを入れて適用すると、NDKがインストールされる。インストールされたら

C:\Users\ユーザ名\AndroidStudioProjects\GPUImage\local.properties

ndk.dir=C\:\\Users\\ユーザ名\\AppData\\Local\\Android\\Sdk\\ndk-bundle

のパスが正しいことを確認する。

さらに

C:\Users\ユーザ名\AndroidStudioProjects\GPUImage\library\build.gradle

の12行目を編集。(gitからバージョンコードを取得している?ようだが、取れずにエラーになるので適当な数値を設定)

versionCode "git rev-list origin/master --count".execute().text.toInteger()
↓
versionCode 1

まだ謎エラーが出るようなら、

ビルド → Clean Project
ビルド → Rebuild Project

を試す。問題がなくなると追加ライブラリのインストールを求められたのでインストール。その後実行すると、サンプルを実機にインストールできた。

プロジェクトに組み込み

C:\Users\ユーザ名\AndroidStudioProjects\プロジェクト名\app\build.gradle

のdependenciesに以下を追加

//GPUImage
compile 'jp.co.cyberagent.android.gpuimage:gpuimage-library:1.4.1'

これだけでプロジェクトにGPUImageが組み込まれるので、あとは呼び出すだけ。以下Intentから画像を選択して、その結果にフィルタをかけて表示するサンプルの抜粋。

// Intentを取得
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, REQUEST_GALLERY);

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_GALLERY && resultCode == RESULT_OK) try {
        InputStream in = getContentResolver().openInputStream(data.getData());
        Bitmap img = BitmapFactory.decodeStream(in);
        in.close();

        // GPUImageで画像を加工
        GPUImage mGPUImage = new GPUImage(this);
        mGPUImage.setFilter(new GPUImageSobelEdgeDetection());
        mGPUImage.setImage(img);
        img = mGPUImage.getBitmapWithFilterApplied();

        // 画像を表示
        imageViewer.setImageBitmap(img);

        Toast.makeText(MainActivity.this, "画像を選択しました", Toast.LENGTH_SHORT).show();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

AndroidでHTTP通信

2年くらい前にAndroidをさわったときは org.apache.http でHTTPリクエストしていたけど、今は使えなくなっているらしい。

どうやら、OkHttpというのを使うのがイマドキらしい。ので試してみた。

確かに org.apache.http を使うよりも、超シンプルなコードになるのでいい感じ。以前作った org.apache.http を簡単に扱えるようにするクラスが用済みになってしまったけど、無事に通信できたので良しとする。

以下、上に書かれた内容と同じだけど自分の作業メモ。

compile 'com.squareup.okhttp:okhttp:2.5.0'

でライブラリを取り込んで、マニフェストファイルで

<uses-permission android:name="android.permission.INTERNET" />

を指定して、以下のコードで通信テスト。リソースファイルは略。

package org.refirio.request;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

import java.io.IOException;

public class MainActivity extends Activity {

    private TextView message;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        message = (TextView)this.findViewById(R.id.message);

        // データ取得(GET)
        Button button_get = (Button)this.findViewById(R.id.button_get);
        button_get.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                new AsyncTask<Void, Void, String>() {
                    @Override
                    protected String doInBackground(Void... params) {
                        String result = null;

                        // リクエストオブジェクトを作って
                        Request request = new Request.Builder()
                                .url("http://httpbin.org/headers")
                                .get()
                                .build();

                        // クライアントオブジェクトを作って
                        OkHttpClient client = new OkHttpClient();

                        // リクエストして結果を受け取って
                        try {
                            Response response = client.newCall(request).execute();
                            result = response.body().string();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                        // 返す
                        return result;
                    }

                    @Override
                    protected void onPostExecute(String result) {
                        message.setText("Result: " + result);
                    }
                }.execute();

            }

        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

Google App EngineでPHPを動作させるメモ

Google App Engineを少しだけ触ってみたのでメモ。

参考サイト

参考にはなったけど、色々端折られた個人メモみたいなので、自分用に改めてメモ。

環境構築

あらかじめWindowsに、Python2.7.xをインストールしておく。(GAEのツール自体がPythonで書かれているため、PHPを動作させる場合でも必要。)

プロジェクト作成

https://console.developers.google.com/project から、プロジェクト名「GAE Test Project」、プロジェクトID「refirio-php-test」で新規にプロジェクトを作成する。(プロジェクト名とプロジェクトIDは任意のものを指定する。)

次に https://console.developers.google.com/project/refirio-php-test/start/appengine にアクセスして解説に従う。

Google App Engine SDK for PHP をインストールし、サンプルコードをダウンロードする。サンプルコードは C:\localhost\home\gae\public_html\refirio-php-test とか、ローカルの適当なディレクトリ内に配置する。

次にサンプルコードを編集する。.playground の内容は以下のとおり。

{
  "project_name": "PHP TEST - refirio",
  "project_description": "Starter code for a Google App Engine app in PHP.",
  "show_files": [
    "helloworld.php",
    "app.yaml"
  ],
  "read_only_demo_url": "https://refirio-php-test.appspot.com/",
  "download_filename": "appengine-try-php.zip"
}

app.yaml の内容は以下のとおり。

application: refirio-php-test
version: 1
runtime: php55
api_version: 1

handlers:
- url: /.*
  script: helloworld.php

helloworld.php の内容は以下のとおり。

<?php

echo 'Hello, GAE!';

公開

デスクトップに作成されたショートカットから「Google App Engine Launcher」を起動する。ここからローカル環境でのテスト実行や、本番環境へのデプロイができる。

デプロイが完了すると、以下のURLからアクセスできる。

Basic認証設定ツール

100番煎じどころではないと思われるツールを作ったので置いておきます。

Basic認証をかけたいディレクトリ内に basic.php などの名前でサーバにアップロードしてアクセスすると、作るべき .htaccess.htpasswd の場所と内容を表示します。先頭に並んでいる test1 とかの部分は、認証させるユーザ名とパスワードです。適当に変更&増減できます。

.htaccess の雛形を作ってくれたり .htpasswd の内容を作ってくれたりするツールは多いけど、AuthUserFile の内容を調べたりするのも面倒なのでそれも自動で。_(:3 」∠ )_

<?php

$users = array(
  'test1' => '1234',
  'test2' => '2345',
  'test3' => '3456',
);
$path = dirname($_SERVER['SCRIPT_FILENAME']);

?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Basic Authentication</title>
</head>
<body>
<h1>Basic Authentication</h1>
<h2><?php h($path) ?>/.htaccess</h2>
<pre>AuthUserFile <?php h($path) ?>/.htpasswd
AuthGroupFile /dev/null
AuthName "Basic"
AuthType Basic
require valid-user
&lt;Files ~ "^.(htpasswd|htaccess)$"&gt;
deny from all
&lt;/Files&gt;</pre>
<h2><?php h($path) ?>/.htpasswd</h2>
<pre><?php

foreach ($users as $username => $password) {
  t($username . ':' . crypt($password) . "\n");
}

?></pre>
</body>
</html>
<?php

function h($data)
{
  $data = htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
  $data = nl2br($data);

  echo $data;
}
function t($data)
{
  $data = htmlspecialchars($data, ENT_QUOTES, 'UTF-8');

  echo $data;
}

?>

Webアプリケーションへの同時アクセス対策メモ

Webアプリケーションへの同時アクセス対策メモ

XAMPPの Apache Bench で同時アクセスを再現するメモ。テストした環境はWindows7。Apache Bench の使い方は以下を参考に。

XAMPPをCドライブ直下にインストールした場合、以下の手順で Apache Bench を使える。

> cd C:\xampp\apache\bin
> ab -n 15 -c 15 http://localhost/~test/ab/

「-n 15 -c 15」で「15人が同時にアクセスする(合計15回アクセス)」状況がテストできる。(「-n 15 -c 1」なら「1人が合計15回アクセスする」状況になるので、同時アクセスにはならない。)

以下で同時アクセスのテストとその対策を行う。

ファイルを使った例

<?php

/*
 * No.2をカウントアップ(最大値100)
 */

if ($fp = fopen('logs/count.log', 'r+')) {
  $data = '';
  while ($line = fgets($fp)) {
    list($id, $count) = explode("\t", rtrim($line));

    if ($id == 2) {
      if ($count < 100) {
        $data .= "$id\t" . ++$count . "\n";
      } else {
        exit('Limit');
      }
    } else {
      $data .= $line;
    }
  }

  rewind($fp);
  fwrite($fp, $data);
  ftruncate($fp, ftell($fp));

  fclose($fp);
} else {
  exit('Error');
}

exit('Complete');

logs/count.log の内容は以下のとおり。

1	10
2	20
3	30
4	40
5	50

これで上のPHPプログラムにアクセスすると、2の行が1カウントアップされる。何度もリロードすると、その回数だけカウントアップされる。

> ab -n 30 -c 30 http://localhost/~test/ab/count.php

30人の同時アクセスを発生させてみると、正しくカウントできないのが確認できる。

<?php

/*
 * No.2をカウントアップ(最大値100)
 */

if ($fp = fopen('logs/count.log', 'r+')) {
  flock($fp, LOCK_EX);  //ファイルロック

  $data = '';
  while ($line = fgets($fp)) {
    list($id, $count) = explode("\t", rtrim($line));

    if ($id == 2) {
      if ($count < 100) {
        $data .= "$id\t" . ++$count . "\n";
      } else {
        exit('Limit');
      }
    } else {
      $data .= $line;
    }
  }

  rewind($fp);
  fwrite($fp, $data);
  ftruncate($fp, ftell($fp));

  fclose($fp);
} else {
  exit('Error');
}

exit('Complete');

ファイルロックを行えば、正しくカウントされるようになる。

データベースを使った例

<?php

/*
 * No.2をカウントアップ(最大値100)
 */

try {
  $pdo = new PDO('mysql:dbname=test;host=localhost', 'root', '1234', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
  $pdo->query('SET NAMES utf8');

  $stmt = $pdo->prepare('SELECT count FROM count_test WHERE id = :id');
  $stmt->bindValue(':id', 2, PDO::PARAM_INT);
  $stmt->execute();

  $data = $stmt->fetch(PDO::FETCH_ASSOC);

  if ($data['count'] < 100) {
    $stmt = $pdo->prepare('UPDATE count_test SET count = count + 1 WHERE id = :id');
    $stmt->bindValue(':id', 2, PDO::PARAM_INT);
    $stmt->execute();
  }
} catch (PDOException $e) {
  exit($e->getMessage());
}

exit('Complete');

count_test の定義は以下のとおり。

CREATE TABLE count_test(
  id    INT UNSIGNED NOT NULL,
  count INT UNSIGNED,
  PRIMARY KEY(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

これで上のPHPプログラムにアクセスすると、2の行が1カウントアップされる。何度もリロードすると、その回数だけカウントアップされる。

ab -n 200 -c 200 http://localhost/~test/ab/count.php

200人の同時アクセスを発生させてみると、正しくカウントできないのが確認できる。

<?php

/*
 * No.2をカウントアップ(最大値100)
 */

try {
  $pdo = new PDO('mysql:dbname=test;host=localhost', 'root', '1234', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
  $pdo->query('SET NAMES utf8');

  $pdo->beginTransaction();  //トランザクション開始

  $stmt = $pdo->prepare('SELECT count FROM count_test WHERE id = :id FOR UPDATE');  //行ロック
  $stmt->bindValue(':id', 2, PDO::PARAM_INT);
  $stmt->execute();

  $data = $stmt->fetch(PDO::FETCH_ASSOC);

  if ($data['count'] < 100) {
    $stmt = $pdo->prepare('UPDATE count_test SET count = count + 1 WHERE id = :id');
    $stmt->bindValue(':id', 2, PDO::PARAM_INT);
    $stmt->execute();
  }

  $pdo->commit();  //コミット
} catch (PDOException $e) {
  $pdo->rollBack();  //ロールバック

  exit($e->getMessage());
}

exit('Complete');

トランザクションと行ロックを行えば、正しくカウントされるようになる。

電話発信用のリンクをPCページで解除

スマートフォン向けページでは、tel: でリンクすれば電話をかけることができます。

<a href="tel:090-1234-5678">090-1234-5678</a>

ただしこの機能はPCサイトでは不要です。この対策に、以下のJavaScriptで電話番号のリンクを解除することができます。

var ua = navigator.userAgent;
if (ua.indexOf('iPhone') < 0 && ua.indexOf('Android') < 0) {
  $('a[href^="tel:"]').each(function() {
    $(this).contents().unwrap();
  });
}

処理の内容は「iPhoneでもAndroidでもなければ、リンク先が tel: が始まるリンクを解除する」としています。

Windows Phone も考慮するならuserAgentの判定は要改良ですが、ひとまずこれで。

UNIXコマンドでサーバ監視して結果をグラフ表示

サーバの監視は普段Zabbixで「Load Average」「CUP Utilization」「Memory」「Disk Space」「Traffic」を監視しているけど、これらを監視する仕組みを一から自作したのでメモ。言わば超簡易Zabbix。

作る理由はただの興味。実際の監視は引き続きZabbixを使うのです。(`・ω・´)

大まかな方針は以下のとおり。

  • uptime などのUNIXコマンドをcronで5分ごとに実行して、結果をファイルに記録する
  • 結果をPHPプログラムで集計する
  • jqPlotでグラフ表示

監視には以下のコマンドを使ってみます。他にもっと適切なコマンドとかがあれば、こっそり教えてくれると喜びます。

■Load Average

$ uptime
 00:00:01 up 170 days,  5:24,  0 users,  load average: 0.00, 0.00, 0.00

■CUP Utilization

$ mpstat 10 5
Linux 2.6.32-504.1.3.el6.x86_64 (www.example.com) 	2015年05月23日 	_x86_64_	(2 CPU)

00時00分01秒  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
00時00分11秒  all    7.74    0.00    1.40    1.35    0.00    0.05    0.65    0.00   88.81
00時00分21秒  all    0.55    0.00    0.40    0.05    0.00    0.00    0.15    0.00   98.85
00時00分31秒  all    0.15    0.00    0.15    1.25    0.00    0.00    0.25    0.00   98.20
00時00分41秒  all    0.20    0.00    0.30    0.65    0.00    0.05    0.15    0.00   98.65
00時00分51秒  all    0.15    0.00    0.20    0.05    0.00    0.00    0.30    0.00   99.30
平均値:   all    1.76    0.00    0.49    0.67    0.00    0.02    0.30    0.00   96.76

■Memory

$ vmstat 10 5
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 7  2 259344 124540 174536 274200    3    1    56    63    1    1  1  0 97  1  1	
 0  0 259344 100656 174536 274276    0    0     0   236  383  269  8  1 89  1  1	
 0  0 259344 129760 174536 274272    0    0     0   209  148  155  1  0 99  0  0	
 0  0 259344 129884 174536 274272    0    0     0   233  121  143  0  0 98  1  0	
 0  0 259344 129760 174544 274272    0    0     0   324  127  141  0  0 99  1  0	

■Disk Space

$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/vda3      100762004 4012036  91624800   5% /
tmpfs             510084       0    510084   0% /dev/shm
/dev/vda1         243823  130875    100148  57% /boot

■Traffic

$ cat /proc/net/dev
Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
    lo: 22940909905 393345389    0    0    0     0          0         0 22940909905 393345389    0    0    0     0       0          0
  eth0: 20118935741 311131513    0    0    0     0          0         0 517575153 2149502    0    0    0     0       0          0
  eth1:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0
  eth2:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0

vmstatmpstat については、計測間隔と計測回数を指定しないと意図した値を得られなかった。また、/proc/net/dev に記録されているのは総トラフィック量なので、その時のトラフィック量を調べるには差分を計算する必要がある。

以下、具体的な記録方法。

まずはroot権限で、コマンドの結果を格納する場所を作ります。また、結果ファイルをPHPから読み出せるようにしておきます。(PHPはwebmasterの権限で実行するという想定。)

# cd /var/log
# mkdir command
# chown webmaster. command

以降はwebmasterユーザで作業。まずは command 内に、コマンドの結果を格納する場所を作ります。

$ mkdir uptime
$ mkdir mpstat_10_5
$ mkdir vmstat_10_5
$ mkdir df
$ mkdir cat_proc_net_dev

結果は /var/log/command/uptime/20150307/2215.log のようなディレクトリ名・ファイル名で格納するものとします。試しにコマンドを実行。

$ mkdir /var/log/command/uptime/`date +'%Y%m%d'`/
$ uptime > /var/log/command/uptime/`date +'%Y%m%d'`/`date +'%H%M'`.log

$ mkdir /var/log/command/mpstat_10_5/`date +'%Y%m%d'`/
$ mpstat 10 5 > /var/log/command/mpstat_10_5/`date +'%Y%m%d'`/`date +'%H%M'`.log

$ mkdir /var/log/command/vmstat_10_5/`date +'%Y%m%d'`/
$ vmstat 10 5 > /var/log/command/vmstat_10_5/`date +'%Y%m%d'`/`date +'%H%M'`.log

$ mkdir /var/log/command/df/`date +'%Y%m%d'`/
$ df > /var/log/command/df/`date +'%Y%m%d'`/`date +'%H%M'`.log

$ mkdir /var/log/command/cat_proc_net_dev/`date +'%Y%m%d'`/
$ cat /proc/net/dev > /var/log/command/cat_proc_net_dev/`date +'%Y%m%d'`/`date +'%H%M'`.log

問題なければ、これらのコマンドをcronに登録。(mkdir では、翌日用のディレクトリを作成するように変更しているので注意。当日用のディレクトリを作成して即結果を保存、は「ディレクトリがありません」のエラーになったため。)

# vi /etc/crontab

00 00 * * * webmaster mkdir /var/log/command/uptime/`date -d '1 days' +'\%Y\%m\%d'`/
*/5 * * * * webmaster uptime > /var/log/command/uptime/`date +'\%Y\%m\%d'`/`date +'\%H\%M'`.log

00 00 * * * webmaster mkdir /var/log/command/mpstat_10_5/`date -d '1 days' +'\%Y\%m\%d'`/
*/5 * * * * webmaster mpstat 10 5 > /var/log/command/mpstat_10_5/`date +'\%Y\%m\%d'`/`date +'\%H\%M'`.log

00 00 * * * webmaster mkdir /var/log/command/vmstat_10_5/`date -d '1 days' +'\%Y\%m\%d'`/
*/5 * * * * webmaster vmstat 10 5 > /var/log/command/vmstat_10_5/`date +'\%Y\%m\%d'`/`date +'\%H\%M'`.log

00 00 * * * webmaster mkdir /var/log/command/df/`date -d '1 days' +'\%Y\%m\%d'`/
*/5 * * * * webmaster df > /var/log/command/df/`date +'\%Y\%m\%d'`/`date +'\%H\%M'`.log

00 00 * * * webmaster mkdir /var/log/command/cat_proc_net_dev/`date -d '1 days' +'\%Y\%m\%d'`/
*/5 * * * * webmaster cat /proc/net/dev > /var/log/command/cat_proc_net_dev/`date +'\%Y\%m\%d'`/`date +'\%H\%M'`.log

これでコマンドの実行結果がどんどん記録されていくので、あとはPHPで読み出すプログラムを作成すればOK。

Windows + コマンドプロンプト + PHPUnit でユニットテスト

今更ながらPHPUnitを試したのでメモ。

概要

PHPUnit3で始めるユニットテストが解りやすかったが情報が古い。でも、概要をつかむには良さそうです。

大まかな内容としては「◯◯の命令を△△の形式で呼び出して、□□の結果が返ってくればOK」というコードをたくさん書いたプログラムを準備しておき、それを実行すれば各命令が正しく実行されたかを知ることができるというもの。(プログラム作成中に不具合を作ってしまっても、即座に検知できる…かもしれない。)

大人数で各々が大量の部品を作るような開発では、上手く導入するととても活躍してくれそう。一人/少人数で作成しているようなプログラムでは、使いどころが難しいかも。(自分が解っていないだけかも。)

導入自体は簡単。

導入

自分の環境に合わせて「Windows+コマンドプロンプト+PHPUnit」でPHPプログラムのテストをしてみたので、手順をメモ。PHPUnit のインストールを主に参考にしています。

まずは公式サイトから phpunit.phar の安定版を入手する。

任意のディレクトリ内(C:\xxx\phpunit とする)に、入手した phpunit.phar を配置する。

C:\xxx\phpunit 内に phpunit.cmd を作成し、以下の内容を記述する。(PHPへのパスは環境に合わせて設定する。)

@C:\xampp\php\php.exe "%~dp0phpunit.phar" %*

コマンドプロンプトで C:\xxx\phpunit 内に移動し、以下のコマンドを実行。以下のようにバージョン情報が表示されれば成功。

C:\xxx\phpunit>phpunit --version
PHPUnit 4.5.0 by Sebastian Bergmann and contributors.

サンプルで動作確認

Getting Started with PHPUnit を参考にテスト。

上ページの内容を参考に C:\xxx\phpunit\src\Money.php (テストしたいクラス)を作成。次に C:\xxx\phpunit\tests\MoneyTest.php (テスト用プログラム)も作成。

コマンドプロンプトから、以下のようにコマンドを実行するとテストできる。

C:\xxx\phpunit>phpunit --bootstrap src/Money.php tests/MoneyTest
PHPUnit 4.5.0 by Sebastian Bergmann and contributors.

.

Time: 31 ms, Memory: 4.00Mb

OK (1 test, 1 assertion)

上のように表示されればテスト成功。

自作のプログラムで動作確認

PHPUnit 用のテストの書き方 を参考にテスト。

まずは C:\xxx\phpunit\src\calculate.php を作成し、掛け算と割り算の計算結果を返す命令を定義。これらの命令が正しく動作しているかテストするものとする。

<?php
function multiplication($x, $y) {
  return $x * $y;
}
function division($x, $y) {
  return $x / $y;
}

C:\xxx\phpunit\tests\calculate.php を作成し、各命令をテストするコードを書く。(計算結果が正しく返ってくればテスト成功とする。)

<?php
require_once 'C:/localhost/home/test/public_html/phpunit/src/calculate.php';
class Calculate extends PHPUnit_Framework_TestCase
{
    public function testCalculate()
    {
        $this->assertEquals(8, multiplication(4, 2));
        $this->assertEquals(2, division(4, 2));
    }
}

コマンドプロンプトからテスト実行。

C:\xxx\phpunit>phpunit tests/calculate
PHPUnit 4.5.0 by Sebastian Bergmann and contributors.

.

Time: 30 ms, Memory: 4.00Mb

OK (1 test, 2 assertions)

上のように表示されればテスト成功。試しに関数の内容を間違ったものにしてテストすると。

FAILURES!
Tests: 1, Assertions: 2, Failures: 1.

のような結果が表示されるので、正しくテストできていることが確認できる。

levis: PHP Framework

最近PHPでプログラムを書くときに時々使っているフレームワークを置いておきます。

有名どころのフレームワークを使うのが一番かと思っていたのですが、ちょっとしたことが簡単にできそうでできなかったり、フレームワークのバージョンアップに合わせてのメンテナンスが大変だったりなので。中小規模の制作だとオレオレフレームワークの方が小回りが利くのです。

名前の由来は、軽量フレームワークなのでラテン語の「levis」から。ちょっと中二病ネーミングです。意味は「軽い」で本来の読みは「レウィス」らしい。このフレームワークの名前としては、英語読みで「レヴィス」にしておきます。

使いながら結構いじっているので、仕様はまだ安定していません。

サーバメモ

今年の後半はサーバ関連の勉強をチョロチョロとしていたので、調べた内容のメモ。

割と色々試したつもりだったけど、サーバ運用の基本の基本でしかないという…。

ここに書いていないことは多分知らない(=設定していない)ことなので、「この設定は必須だろう」とかあればツッコミ歓迎です。
「こんなこともwww知らないのwww」
とかツッコミをくれたら、凹みながらこっそり糧にしておきます。

負荷対策のチューニングなどは、頭の中を整理して、色々実験してから加筆したい。

さくらのクラウドは勉強中。GAEはまだ手付かず。メールサーバも手付かず。セキュリティと負荷対策は随時勉強中。

ページ移動

ユーティリティ

カテゴリー

検索

エントリー検索フォーム
キーワード

過去ログ

過去ログ表示フォーム
キーワード

Feed