mPDF (5.7.4) はタイムゾーン設定を勝手に書き換えるので注意
HTML で書かれたコードから PDF を出力できる mPDF という PHP ライブラリがある。HTML と CSS を理解していれば思い通りに、とまではいかないまでも、それなりにレイアウトすることができる。
あるときこの mPDF を使っていたところ、出力される日時がずれてしまう問題が発生した。 date_default_timezone_set() を使ってタイムゾーンを設定しているのにおかしいと思い、コードを追いかけると mPDF を読み込む段階でタイムゾーン設定が書き換わっていることが分かった。
<?php date_default_timezone_set('Asia/Tokyo'); echo date_default_timezone_get(); // => Asia/Tokyo require_once '/path/to/mpdf.php'; echo date_default_timezone_get(); // => Europe/London
原因は mpdf.php の 54 行目に書かれている次の一文。
if (ini_get("date.timezone")=="") { date_default_timezone_set("Europe/London"); }
このコードではスクリプトでタイムゾーンが設定されていても、ini ファイルにタイムゾーンの設定がなければ date_default_timezone_set("Europe/London") が実行されてしまう。もしタイムゾーンの設定がどこにもなければ PHP はデフォルトのタイムゾーンである UTC を使用するので、わざわざタイムゾーンを設定する必要はない。よって mpdf.php の 53〜55 行目をコメントアウトして使用する。
mPDF の GitHub プロジェクトでもこの問題がバグとして報告されている。
PostgreSQL でユーザとデータベースを新しく作る手順
備忘録。psql から行う。
# sudo -u postgres psql
または
> psql -U postgres
ユーザの作成
CREATE USER ユーザ名 WITH ENCRYPTED PASSWORD 'パスワード';
ユーザ一覧
SELECT * FROM pg_shadow;
ユーザの削除
DROP USER ユーザ名;
データベースの作成
CREATE DATABASE データベース名 OWNER ユーザ名 ENCODING 'UTF-8';
Swift でネットワーク状況を調べる
iOS アプリでネットワークへの接続状況を調べるとき、Objective-C では Tony Million による Reachability というライブラリが使用できた。
一方 Swift では IJReachability や Reachability.swift が使える。ここではネットワーク状況の変化を検出できる Reachability.swift を用いる。
ライブラリを使う準備
Reachability.swift から “Download ZIP” を選び、ライブラリをダウンロードする。
ダウンロードしたファイルを展開し、 Reachability.swift を AMReachability.swift にリネームする。さらに Xcode でこのファイルを開き、 “Edit All in Scope” を使ってクラス名を Reachability から AMReachability へ変更しよう。
こうするのは Tony Million のライブラリを使って App の審査に通らなかったという報告があるためだ。
WARNING there have been reports of apps being rejected when Reachability is used in a framework. The only solution to this so far is to rename the class.
https://github.com/tonymillion/Reachability
ライブラリをプロジェクトに追加する
ライブラリの使い方は簡単、先ほど作った AMReachability.swift をプロジェクトにコピーする。
画面左のファイル一覧に AMReachability.swift をドラッグすると、次のような画面が出るはずなので、“Copy items if needed” にチェックを入れ “Finish” を選ぶ。
Reachability.swift の使い方
使い方はいたって簡単。
単に現在のネットワーク状況を調べるときは次のようにする。
let reachability = AMReachability.reachabilityForInternetConnection() if reachability.isReachable() { println("インターネット接続あり") } else { println("インターネット接続なし") }
もしインターネット接続ではなく、単にローカルネットワークに接続しているかどうかを調べるときは、代わりに reachabilityForLocalWiFi() を用いる。
ネットワークに接続や切断したときに何か処理をしたいという場合は次のように書ける。
let reachability = AMReachability.reachabilityForInternetConnection() reachability.whenReachable = { reachability in println("インターネット接続あり") } reachability.whenUnreachable = { reachability in println("インターネット接続なし") }
Dnsmasq を広告ブロックツールとして使う
Dnsmasq は DNS サービスを提供することができるソフトウェアだ。簡単な設定で名前解決のレコードほ書き換えることができる。これを利用して広告をブロックする。
この記事の対象読者は、次のすべてに当てはまることを想定している。
- OS X を使っている(ここで試したのは 10.9.5/Mavericks, 10.10.5/Yosemite)
- 今使っているマシンのネットワーク設定ができる
- ターミナル上での操作に慣れている
- ローカルに Web サーバを設定して使っている、あるいは設定できる
Dnsmasq のインストール
Dnsmasq のインストールには OS X であれば Homebrew で行える。次のコマンドを実行するだけだ。
brew install dnsmasq
(しばらく Homebrew を更新していない場合はこの前に brew update を実行するとよい)
Dnsmasq の初期設定
Dnsmasq の設定ファイルをコピーする。
cp -a `brew --prefix dnsmasq`/dnsmasq.conf.example /usr/local/etc/dnsmasq.conf
設定ファイルは初期状態ではほぼコメントだった。なので、役立ちそうなコメントを除いてすべて消し、次の行を書き加えた。
# /usr/local/etc/dnsmasq.conf # LaunchAgents で動かすため、常にforgroundで起動 keep-in-foreground # Dnsmasq 用の resolv.conf resolv-file=/etc/resolv.dnsmasq.conf # ローカルからの問い合わせのみ受け付ける listen-address=127.0.0.1
Launchctl から起動できるように plist ファイルを LaunchAgents ディレクトリにコピーする。
sudo cp `brew --prefix dnsmasq`/homebrew.mxcl.dnsmasq.plist /Library/LaunchAgents
OS X で使われている resolv.conf を dnsmasq 用にコピーする。
sudo cp /etc/resolv.conf /etc/dnsmasq.conf
resolv.conf には OS X の環境設定で設定されている DNS サーバのアドレスが登録されている。DHCP で DNS サーバを自動取得している場合、取得したサーバのアドレスが登録される。そのため、もし MacBook をいろいろな場所で複数のネットワークに接続する必要がある場合は面倒かもしれない。ただし LAN 上の DNS を参照する必要がない場合、Google の提供する Public DNS に向けておくという手もある。
Dnsmasq の起動と終了
Dnsmasq の起動と終了には launchctl を用いる。ps ax | grep [d]nsmasq などで起動を確認できる。
# 起動 sudo launchctl load -w /Library/LaunchAgents/homebrew.mxcl.dnsmasq.plist # 終了 sudo launchctl unload -w /Library/LaunchAgents/homebrew.mxcl.dnsmasq.plist
もし OS X 起動時に自動的に起動させたい場合は、LaunchAgents のかわりに LaunchDaemons に homebrew.mxcl.dnsmasq.plist をコピーする。(LauchDaemons は OS の起動時、LaunchAgents は各ユーザのログイン時に実行される。dnsmasq の起動にはスーパーユーザ権限が必要なため、各ユーザの権限で実行される LaunchAgents では自動起動しない)
OS X が参照する DNS サーバを dnsmasq に向ける
次のコマンドのほか、OS X の環境設定パネルからも可能。“Wi-Fi” の部分は適宜書き換えてほしい。
sudo networksetup -setdnsservers Wi-Fi 127.0.0.1
Dnsmasq を使うのをやめ、DHCP での自動取得に戻したい場合は次のコマンドを使う。
sudo networksetup -setdnsservers Wi-Fi Empty
広告を提供しているドメインをローカルに向ける
dnsmasq.conf に次の設定を追記した。これで設定したドメインおよびそのサブドメインがローカルへ向く。
# AD Block
address=/2o7.net/127.0.0.1
address=/a.adroll.com/127.0.0.1
address=/ad-arata.com/127.0.0.1
address=/adcash.com/127.0.0.1
address=/addthis.com/127.0.0.1
address=/adlantis.jp/127.0.0.1
address=/adkengage.com/127.0.0.1
address=/adjust-net.jp/127.0.0.1
address=/adresult.jp/127.0.0.1
address=/adtechjp.com/127.0.0.1
address=/advertising.com/127.0.0.1
address=/advg.jp/127.0.0.1
address=/agkn.com/127.0.0.1
address=/api.flipdesk.jp/127.0.0.1
address=/api.unthem.com/127.0.0.1
address=/apvdr.com/127.0.0.1
address=/atwola.com/127.0.0.1
address=/b3.yahoo.co.jp/127.0.0.1
address=/bidswitch.net/127.0.0.1
address=/bigmining.com/127.0.0.1
address=/bktrx.com/127.0.0.1
address=/bluekai.com/127.0.0.1
address=/brightcove.com/127.0.0.1
address=/cas.criteo.com/127.0.0.1
address=/cdn.bigmining.com/127.0.0.1
address=/cdn.cxense.com/127.0.0.1
address=/cdn.optimizely.com/127.0.0.1
address=/company-target.com/127.0.0.1
address=/coremetrics.com/127.0.0.1
address=/criteo.com/127.0.0.1
address=/d.adroll.com/127.0.0.1
address=/deqwas.net/127.0.0.1
address=/domdex.com/127.0.0.1
address=/doubleclick.net/127.0.0.1
address=/dsum-sec.casalemedia.com/127.0.0.1
address=/edge.simplereach.com/127.0.0.1
address=/eimg.jp/127.0.0.1
address=/exoclick.com/127.0.0.1
address=/fout.jp/127.0.0.1
address=/genieesspv.jp/127.0.0.1
address=/gmossp-sp.jp/127.0.0.1
address=/googleadservices.com/127.0.0.1
address=/googlesyndication.com/127.0.0.1
address=/googletagmanager.com/127.0.0.1
address=/googletagservices.com/127.0.0.1
address=/gssp.asia/127.0.0.1
address=/gsspat.jp/127.0.0.1
address=/gsspcln.jp/127.0.0.1
address=/gssprt.jp/127.0.0.1
address=/i-mobile.co.jp/127.0.0.1
address=/im-apps.net/127.0.0.1
address=/img.macromill.com/127.0.0.1
address=/impact-ad.jp/127.0.0.1
address=/js.ptengine.jp/127.0.0.1
address=/js.revsci.net/127.0.0.1
address=/loading-delivery1.com/127.0.0.1
address=/logly.co.jp/127.0.0.1
address=/microad.jp/127.0.0.1
address=/moatads.com/127.0.0.1
address=/mtcs.nhk.or.jp/127.0.0.1
address=/nakanohito.jp/127.0.0.1
address=/native.sharethrough.com/127.0.0.1
address=/nr-data.net/127.0.0.1
address=/omt.shinobi.jp/127.0.0.1
address=/openx.net/127.0.0.1
address=/openxmarket.jp/127.0.0.1
address=/outbrain.com/127.0.0.1
address=/pixel.facebook.com/127.0.0.1
address=/popin.cc/127.0.0.1
address=/pubmatic.com/127.0.0.1
address=/quantumads.com/127.0.0.1
address=/revcontent.com/127.0.0.1
address=/revsci.net/127.0.0.1
address=/rlcdn.com/127.0.0.1
address=/rtoaster.jp/127.0.0.1
address=/rubiconproject.com/127.0.0.1
address=/s.adroll.com/127.0.0.1
address=/s.thebrighttag.com/127.0.0.1
address=/scorecardresearch.com/127.0.0.1
address=/secure.eloqua.com/127.0.0.1
address=/sh.adingo.jp/127.0.0.1
address=/skimresources.com/127.0.0.1
address=/socdm.com/127.0.0.1
address=/spdeliver.i-mobile.co.jp/127.0.0.1
address=/static.quant.jp/127.0.0.1
address=/taboola.com/127.0.0.1
address=/tacoda.net/127.0.0.1
address=/textad.net/127.0.0.1
address=/trafficfactory.biz/127.0.0.1
address=/uliza.jp/127.0.0.1
address=/xml.affiliate.rakuten.co.jp/127.0.0.1
address=/yads.c.yimg.jp/127.0.0.1
address=/b90.yahoo.co.jp/127.0.0.1
address=/b91.yahoo.co.jp/127.0.0.1
address=/yads.yahoo.co.jp/127.0.0.1
address=/ybx.yahoo.co.jp/127.0.0.1
address=/yjtag.jp/127.0.0.1
address=/ziyu.net/127.0.0.1
ローカル Web サーバを設定する
OS X では Apache が入っているのでそれを使った。設定ファイルは /etc/apache2/httpd.conf にある。
ローカル Web サーバを使っていない場合は次の設定をする。
# デフォルトではこうなっているはずだ DocumentRoot "/Library/WebServer/Documents" # このセクションに記述する <Directory "/Library/WebServer/Documents"> ... # この2行を追記 ErrorDocument 403 "404 AD Block" ErrorDocument 404 "404 AD Block" ... </Directory>
すでにローカル Web サーバを使っている場合はバーチャルホストを設定し、特に名前を設定したホスト以外はダミーページを表示するようにする。
<VirtualHost *:80> ServerName localhost ServerAdmin webmaster@localhost DocumentRoot "/Users/theUser/Sites/dummy" ErrorLog /dev/null CustomLog /dev/null common env=0 <Directory "/Users/theUser/Sites/dummy"> ErrorDocument 403 "404 AD Block" ErrorDocument 404 "404 AD Block" </Directory> </VirtualHost>
効果測定
これで大半の広告がブロックされたので、ためしに広告がいくつか入ったページの読み込み速度を測定した。
広告スクリプトの配置されているドメインの名前解決が必要なくなったぶん、かなり高速になった。
- http://www.tenki.jp/forecast/4/20/5610/17201.html が 7.31 秒から 1.14 秒 (84 % 高速)
参考
- Dnsmasq - network services for small networks.
- Mountain Lionにdnsmasqをインストールするメモ
- プロセスの源流を見に行く
- LaunchAgents と LaunchDaemon の違いについて
- DHCP で取得した DNS サーバを使いつつ dnsmasq を使う
「管理者として実行する」のチェックが外せない場合の対処法
どういうわけか分からないが、ある日突然 Windows 7 上でプログラムを起動するときにユーザ アカウント制御のダイアログが表示されるようになってしまった。
実行ファイルのプロパティを見ると、「管理者としてこのプログラムを実行する」にチェックが入ったまま外せなくなっている。解決方法はないかとレジストリ エディターを開いてプログラムのファイル名で検索したところ、次の場所にある値を削除すればよいことが分かった。HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
名前が実行ファイルのパス、値が RUNASADMIN となっているものを削除する。
これで「管理者としてこのプログラムを実行する」のチェックが外れ、ユーザ アカウント制御のダイアログも出なくなった。- Troublesome > 各種設定 > 『互換性』タブ
- RUNASADMIN 以外の値の意味はこちらに解説されている