Do You PHP はてな このページをアンテナに追加 RSSフィード Twitter

2016-07-01

[]JsViewsチュートリアル - テンプレートのリンクを解除する

JavaScript製でjQuery非依存なテンプレートエンジンであるJsRender/JsViewsを使ったチュートリアルを書いてみようと思います。

以前に書いたエントリJsRender入門 - Do You PHP はてなも参照してください。

今回やること

JsViewsでテンプレートのリンクを解除する

コード

<html>
<body>
<div id="list_simple"></div>
<hr/>
<button id="add">add</button>
<button id="unlink">unlink</button>
<button id="empty">empty</button>

<script src="https://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="http://www.jsviews.com/download/jsviews.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
    var fruits = {};

    $.templates('#template').link("#list_simple", fruits);

    $(document)
        .on('click', '#add', function(ev) {
            $.observable(fruits).setProperty({
                code: "99",
                name: "ドリアン"
            });
        })
        .on('click', '#unlink', function(ev) {
            $.observable(fruits).setProperty({
                code: "01",
                name: "バナナ"
            });

            // リンクを解除する。コンテンツはそのまま
            $.unlink('#list_simple');
        })
        .on('click', '#empty', function(ev) {
            // 空にすることで、リンクも自動的に解除される
            $('#list_simple').empty();
        });
});
</script>

<script id="template" type="text/x-jsrender">
{^{if #data}}
    <div id="inner">
        {^{>code}}/{^{>name}}
    </div>
{{/if}}
</script>
</body>
</html>

説明

テンプレートへのリンクを解除する場合、jsViewsのunlinkメソッドを使用します。ただし、unlinkメソッドテンプレート内のscriptタグを削除するだけ、つまり、リンクが解除されるだけで描画済みのコンテンツはそのままになりますので、必要に応じてコンテンツのクリアなどを行う必要があります。また、リンクされたノードが削除された場合、自動的にリンクも削除されます。

JSFiddleで動作を見る

参照

[]JsViewsチュートリアル - リンクしたテンプレートをまるごと差し替える

JavaScript製でjQuery非依存なテンプレートエンジンであるJsRender/JsViewsを使ったチュートリアルを書いてみようと思います。

以前に書いたエントリJsRender入門 - Do You PHP はてなも参照してください。

今回やること

JsViewsでリンクしたテンプレートを別のテンプレートに差し替える

コード

<html>
<body>
<div id="list_simple"></div>
<hr/>
<button id="add">add</button>
<button id="switch">switch</button>

<script src="https://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="http://www.jsviews.com/download/jsviews.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
    var fruits = {
        foo: 'foo',
        bar: 'bar'
    };
    $.templates({
        template1: "#template1",
        template2: "#template2"
    });

    var current_template = $.templates.template1;
    $.link.template1("#list_simple", fruits);

    $(document)
        .on('click', '#add', function(ev) {
            $.observable(fruits).setProperty({
                code: "99",
                name: "ドリアン"
            });
        })
        .on('click', '#switch', function(ev) {
            /**
             * テンプレートを差し替えるviewオブジェクトを取得する
             */
            var $view = $.view('#inner');   // $.view($('#inner'))でもOK
            if (current_template == $.templates.template1) {
                current_template = $.templates.template2;
            } else {
                current_template = $.templates.template1;
            }

            /**
             * テンプレートを差し替える
             *
             * コンパイル済みテンプレートでない場合、$.templates('#template1')の
             * ような書式でもOK
             */
            $view.tmpl = current_template

            /**
             * 新しいテンプレートで再描画
             */
            $view.refresh();
        });
});
</script>

<script id="template1" type="text/x-jsrender">
{^{if #data}}
    <div id="inner">
        {^{>code}}/{^{>name}}
    </div>
{{/if}}
</script>
<script id="template2" type="text/x-jsrender">
    <h1 id="inner">
        {^{>foo}}:{^{>bar}}
    </h1>
</script>
</body>
</html>

説明

リンクしたテンプレートを何らかのイベントが発生したタイミングで、別のテンプレートに差し替える事もできます。この場合、viewオブジェクトのtmplプロパティに別のテンプレートオブジェクトを代入し、viewオブジェクトのrefreshメソッドを呼び出すことで新しいテンプレートを使って再描画させます。

JSFiddleで動作を見る

参照

2016-04-25

[]BluetoothHHKB Professionalが到着!

PFUダイレクトAmazonショップで予約していたBluetoothHHKB Professionalが無事到着しました。

購入したのは英語配列(PD-KB600B)です。

プチ開封の儀

到着した荷物の箱を開けると。。。おおお、これですよこれ。予約特典(先着)のスマートケースも付いてきました。

f:id:shimooka:20160425113414j:image

化粧箱。

f:id:shimooka:20160425113759j:image

箱は重要じゃない、中身が大事です。今回初めて「墨」を購入しましたがダークグレーというか意外と黒くないんですね。

f:id:shimooka:20160425113832j:image

会社で使ってる初代HHKB Professional(PD-KB300)と並べたところ。初代はもう白色と言うより蛍光灯焼けしてクリーム色になってますけど(涙)

f:id:shimooka:20160425113856j:image

ちょっとタイピングしたところ、初代と比べてかなり「カチャカチャ感」がないです。あと、タッチがちょっと軽くなってる気がします。Professional2からそうなんでしょうか。。。

環境設定

普段はDELL製ノートPC+Windows7(64Bit版)+初代HHKB Professional+トリニティーワークス社のUSJP Proという組み合わせで使ってます。

USJP Proでやってることは

  • キーボード配列変換(106→101)
  • CapsLockとctrlキーの入れ替え(ノートPC側も含む)

の2つなのですが、今回購入したHHKBも含めて

  • 初代HHKBも今までどおり使える
  • BluetoothHHKBも初代と同様に使える
  • ノートPCのCapsLockはctrlキーと入れ替え

という環境にしたいので、USJP Proをやめてレジストリを直接いじることにしました。

キーボード配列変換

使用するキーボード毎に106(ノートPCのキーボード)と101(HHKB×2)を切り替える必要があります。ググってみたところ、HID毎に設定を上書きできることが分かったので早速実施。手順は以下のエントリを参考にしました。

(1)まずは、デバイスマネージャで2台分のHHKBハードウェアIDをそれぞれ確認。必要であればベースコンテナーIDも。

f:id:shimooka:20160425151351p:image

(2)レジストリエディタを使って、それぞれの所定の場所にKeyboardTypeOverride、KeyboardSubtypeOverrideを追加

f:id:shimooka:20160425151830p:image

CapsLockとctrlキーのキーマッピング変更

こちらもググるといろいろ情報が出てきますが、よく考えるとCapsLockキーがctrlキーになれば要件は満たせるわけで入れ替える必要がない事に気づきました。ということで、以下のサイトを参考にレジストリを変更。

実際には、コピペでregファイルを作って実行しました。

f:id:shimooka:20160425171042p:image

OS再起動して動作確認

レジストリを変更したらWindows再起動。ノートPC・初代HHKBBluetoothHHKBでそれぞれ動作確認し、問題がないことを確認しました。

まとめ

今日のお昼ごろから使ってますが、ようやくキーボード周りのケーブルが無くなって手元がすっきりしました。「カチャカチャ感」がないのが気になります(汗)が、まあそのうち慣れるでしょう。

f:id:shimooka:20160425171424j:image

後でAndroid端末にも繋げてみるか。。。

2016-04-12

[]ついにHHKBBluetooth版が発売!

ずーっと「あれば良いのに」と思っていたHHKB Bluetooth版がPFUから発売されることになったようです!

発売日は2016/04/22。PFUダイレクトAmazonショップで予約受付中です。

今のところ、色は墨のみ。英語配列・無刻印・日本語配列の3タイプ。

速攻で予約しました。当然、英語配列です。到着が楽しみ!:-)

2016-03-03

[]Motorola Moto 360(1st Gen)にAndroid 6.0.1が降ってきた

久々のエントリですが、PHPネタではありません。

2nd Genがリリースされて陽の目が当たらなくなったMoto 360(1st Gen)ですが、TaskerAutoVoiceAutoWearのゴールデンコンビのおかげで個人的にはまだまだ現役です。以前よりも付ける時間が長くなり、仕事中はほぼつけっぱなしです。リューズ取れちゃったけど。。。

で、今朝もいつも通り腕につけてふと見ると、おや?Moto360のようすが・・・

f:id:shimooka:20160303121411p:image

カードを開いてみると。。。

f:id:shimooka:20160303121412p:image

おお!jugglyさんでアップデートされるらしいとあったけど半信半疑でした。ごめんなさい(汗)

会社に到着後、アップデートを実行。

f:id:shimooka:20160303114137j:image

f:id:shimooka:20160303114554j:image

待つこと5分。無事、Android 6.0.1(MEC23I)になりました。

ちょっといじってみるとメニューがちょっと変わったっぽいのでまとめておきます。

手首のジェスチャー

設定アプリから表示されるメニューに「操作」としてまとめられたようです。

f:id:shimooka:20160303130911p:image

ここに手首の操作の有効無効のスイッチがあります。また、チュートリアルを起動して一通りジェスチャーを確認できます。

f:id:shimooka:20160303130910p:image

にしても、腕を上げにやるのって結構難しくないのかな。。。

権限管理

新しく「権限」メニューが追加されています。

f:id:shimooka:20160303130908p:image

開いてみると、インストールされているアプリの一覧が表示されます。

f:id:shimooka:20160303130907p:image

アプリを選択すると権限の一覧が表示されるので、ここで権限の有効無効の切り替えを行えるようです。

f:id:shimooka:20160303130909p:image

2015-11-10

[]USB接続&フルHDモバイルディスプレイASUS MB169B+を買った

皆さんどんな環境で開発してます?

ノートPC単体?自作デスクトップデュアルディスプレイ?もしかして3枚?4枚?外部キーボード

自分の会社での環境は、15インチノートPC+お古のCinemaディスプレイデュアルディスプレイHHKBな感じです。片方のディスプレイターミナルエディタブラウザの開発ツールを開いてゴリゴリやって、もう片方にブラウザを広げっぱなしにして動作確認する感じにしてます。

で、諸々の事情で平日に自宅作業することがあるんですが、

  • 家にはホコリをかぶった17インチCRTしかない
  • まさか、リビングに持ってきて使うのもどうよ
  • 高さが全然違うし。。。

という状況なのでノートPC単体で使ってました。でも、ウィンドウが重なってしまって確認したい情報を同時に見られないのはさすがに効率が悪い。悪すぎる。

ということで、前から気になっていたASUS MB169B+を思い切って購入。

Amazonでちょうど3万円ぐらい。

ついでに、スタンドも購入。こっちは安いので充分。

ASUSの製品ページには本体800gとありますが、持った感じはそれよりも軽く感じます。15インチのタブレットからバッテリー抜いたような感じです。

PCとの接続はUSBなので超簡単。電源もUSBから供給なので余計なコード類はありません。PC側のUSBポート挿せばディスプレイドライバーがインストールされ、再起動したら何事もなかったようにデュアルディスプレイ化完了。

f:id:shimooka:20151110134646p:image

嫁さんが使っているMacBook AirでもASUSのサイトからディスプレイドライバーをダウンロードしてインストールすれば問題なく認識されました。

自分のノートPCに繋いだらこんな感じです。

f:id:shimooka:20151110114213j:image

f:id:shimooka:20151110114236j:image

使用感ですが、15.6インチワイドということもあり正面に据えるとちょうどいいサイズです。輝度は左側にボタンがあるのでそれで調整可能。淡い色の表現に難があるかな?という感じですが、コードを書く分にはあまり問題にはならないかと思います。

やっぱデュアルディスプレイ良いですね。これならもっと早く買っといても良かったかも。

2015-07-29

[]PHP 7 Compatibility Checker(php7cc)を触ってみた

珍しくPHPネタを連投してます;-)

β2がリリースされてだいぶ実体が見えてきたPHP7ですが、PHP5.xから多くの改良、機能の追加・非推奨化・廃止、また仕様変更が含まれています。既存のコードがPHP7で動作するかどうかを

で、既存のコードがPHP7で動作するかどうかをチェックするツールがGitHubで公開されていましたので、ちょっと触ってみました。

php7cc is a command line tool designed to make migration from PHP 5.3-5.6 to PHP 7 easier. It searches for potentially troublesome statements in existing code and generates reports containing file names, line numbers and short problem descriptions. It does not automatically fix code to work with the new PHP version.

sstalle/php7cc

Introductionにもあるとおり、あくまでlintのような"コードチェッカー"であり、コードを修正してくれるツールではありません。また、PHP7はまだ開発中なのですべての変更点を洗い出せるわけではないことに注意です。

環境

  • CentOS6.4
  • PHP5.6.11

インストール

README.mdのInstallationに書かれているとおり、composer経由でインストールします。

$ PATH=/usr/local/lib/php56/bin:$PATH php ./composer.phar create-project sstalle/php7cc php7cc --stability=dev
        :
Writing lock file
Generating autoload files
Do you want to remove the existing VCS (.git, .svn..) history? [Y,n]? n
$ 

インストールの最後にVCS履歴を削除するかどうかを聞かれます。ここで"no"としておけば、今後git pullで更新できるようになるようです。

チェック対象のPHPスクリプト

PHP7.0.0β2に含まれているUPGRADINGファイルに記載されているコードを使ってチェック用のスクリプト(UPGRADING.php)を作ってみました。

<?php
/**
 * @see https://raw.githubusercontent.com/php/php-src/php-7.0.0beta2/UPGRADING
 */

/**
 * Indirect variable, property and method references are now interpreted with
 * left-to-right semantics. Some examples:
 */
$$foo['bar']['baz']; // interpreted as ($$foo)['bar']['baz']
$foo->$bar['baz'];   // interpreted as ($foo->$bar)['baz']
$foo->$bar['baz'](); // interpreted as ($foo->$bar)['baz']()
Foo::$bar['baz']();  // interpreted as (Foo::$bar)['baz']()


/**
 * The global keyword now only accepts simple variables. Instead of
 */
global $$foo->bar;


/**
 * Parentheses around variables or function calls no longer have any influence
 * on behavior. For example the following code, where the result of a function
 * call is passed to a by-reference function
 */
function getArray() { return [1, 2, 3]; }

$last = array_pop(getArray());
// Strict Standards: Only variables should be passed by reference
$last = array_pop((getArray()));
// Strict Standards: Only variables should be passed by reference


/**
 * Array elements or object properties that are automatically created during
 * by-reference assignments will now result in a different order.
 */
$array = [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
    :

全体はGistにありますので参照してみてください。

実行してみる

インストール後に生成されるphp7ccディレクトリ直下にbinディレクトリがあり、その中にあるphp7cc.phpファイルを実行します。引数PHPスクリプトを含むパスもしくはファイル名を指定します。パスを指定した場合は、第2引数拡張子(カンマ区切りで複数指定可能)できます。

$ PATH=/usr/local/lib/php56/bin:$PATH php ./php7cc/bin/php7cc.php ./UPGRADING.php

File: ./UPGRADING.php
Line 7. Indirect variable, property or method access: /**
 * Indirect variable, property and method references are now interpreted with
 * left-to-right semantics. Some examples:
 */
${$foo['bar']['baz']};
Line 8. Indirect variable, property or method access: // interpreted as ($$foo)['bar']['baz']
$foo->{$bar['baz']};
Line 9. Indirect variable, property or method access: // interpreted as ($foo->$bar)['baz']
$foo->{$bar['baz']}();
Line 10. Indirect variable, property or method access: // interpreted as ($foo->$bar)['baz']()
Foo::$bar['baz']();
Line 16. Complex variable without curly braces in global keyword: // interpreted as (Foo::$bar)['baz']()
/**
 * The global keyword now only accepts simple variables. Instead of
 */
global ${$foo->bar};
Line 37. Possible array element creation during by-reference assignment: $array['a'] =& $array['b'];
Line 53. Empty list assignment: /**
 * Empty list() assignments are no longer allowed. As such all of the following
 * are invalid:
 */
list();
Line 54. Empty list assignment: list(, , );
Line 55. Empty list assignment: list();
Line 99. Possible adding to array on the last iteration of a by-reference foreach loop: $array[1] = 1;
Line 109. Duplicate function parameter name "unused": public function foo($a, $b, $unused, $unused)
{
}
Line 122. Function argument(s) returned by "func_get_arg" might have been modified: func_get_arg(0);
Line 142. Invalid octal literal 0781: 7;
Line 172. String containing number in hexadecimal notation: '0x123';
Line 173. String containing number in hexadecimal notation: '0x123';
Line 174. String containing number in hexadecimal notation: '0xe';
Line 174. String containing number in hexadecimal notation: '0x1';
Line 176. String containing number in hexadecimal notation: '0x1';
Line 184. String containing number in hexadecimal notation: '0xffff';
Line 197. Unicode codepoint escaping "\u{xyz}" in a string: '\\u{xyz}';

Checked 1 file(s) in 0.048255 second(s)
$ 

用意したPHPスクリプトのすべてではないですが、結構いい感じにチェックできているんじゃないでしょうか?

ちょっとだけ深堀り

PHPスクリプトの解析にはPHP Parserが使われています。php7cc側では、PhpParser\NodeVisitorAbstractクラスを継承したAbstractVisitorクラスが用意されており、それを継承した各Visitorクラスで「何をチェックするか」が実装されています。

たとえば、func_get_arg/func_get_args関数戻り値の変更に対するチェッカー(php7cc/src/NodeVisitor/FuncGetArgsVisitor.php)は次のような感じです。

<?php

namespace Sstalle\php7cc\NodeVisitor;

use PhpParser\Node;
use Sstalle\php7cc\Helper\NodeHelper;

class FuncGetArgsVisitor extends AbstractVisitor
{

    public function enterNode(Node $node)
    {
        if (!NodeHelper::isFunctionCallByStaticName($node)) {
            return;
        }

        /** @var Node\Expr\FuncCall $node */
        $functionName = $node->name->toString();
        if ($functionName == 'func_get_arg' || $functionName == 'func_get_args') {
            $this->addContextMessage(
                sprintf('Function argument(s) returned by "%s" might have been modified', $functionName),
                $node
            );
        }
    }
}

まとめ

今年中には正式リリースされる感じのPHP7ですが、こういうツールを上手く使って楽に移行をしたいですね(希望的観測)。。。(汗)

というか、サードパーティ製の拡張モジュールが対応してくれるのか不安だなぁ。。。

2015-07-24

[]GoPHP7とGoPHP7-ext

何だかGoPHP5を思い出しますが、すでにGoPHP7のサイトがあるようです。

TOPページにはリリースバージョンが表示されるだけでリンクも何もないんですが。。。

で、各種拡張モジュールのPHP7への対応状況をまとめた情報も公開されています。

ここの「Catalog」タブをクリックすると、対応状況一覧へのリンクが現れます。

これを見てみると、コアモジュールはかなりの割合でPHP7に対応しているようです。一方で、Xdebugmemcached、runkitなどのサードパーティ製モジュールはまだまだのようですね。

とりあえず、ssh2とyaml拡張モジュールについてはPHP7.0.0β2との組み合わせで問題なくbuildできることを確認しました。