LiveReloadの便利さを手軽に非Gruntプロジェクトでも使う方法

Grunt+LiveReloadが便利なのだけど、サーバサイドがメインのもので、
concat/cssmin/jsmin/htmlminしないのにGrunt watchするのめんどくさいですね?

と思ったら公式のReload発火アプリケーションがありました。

http://livereload.com/

LiveReload.com
LiveReload.com

2014/7/22現在WindowsはAlpha版なので無料ですが、Mac用は$9.99なんですね…。

ともかくインストーラを手に入れて実行。

リロードの設定をする

にょろにょろとインストール実行後、

LiveReload
+addから監視したいディレクトリを指定するだけ。

例えばVagrantで共有してるhtdocsディレクトリとか。

後は、Google ChromeでリロードしたいURLを開いてから、
Gruntと連携するときにも使っていたGoogle Chrome用LiveReloadプラグインをONにすると、
指定したディレクトリ内のファイルが上書きされたタイミングでリロードされます。

試したのはWindows(v0.9.2.0 – Alpha)版なので、ディレクトリとリロードするURLの関連などは設定できないようですね。

PHP5.4.30 + MySQL5.6.19で文字化けに対応。

ちなみに、PHPからは以下のようにつないでいます。

// PDO接続(PHP 5.3.6以降だとcharsetが使えます
$dsn="mysql:dbname=%s;host=%s;charset=utf8";

文字化けする環境と、/etc/my.cnfに対応したもの

$ cat /etc/redhat-release
CentOS release 6.5 (Final)

$ mysql --version
mysql  Ver 14.14 Distrib 5.6.19, for Linux (x86_64) using  EditLine wrapper

$ php -v
PHP 5.4.30 (cli) (built: Jun 25 2014 15:27:51)

$ yum list installed | grep mysql
mysql-community-client.x86_64        5.6.19-2.el6    @mysql56-community
mysql-community-common.x86_64        5.6.19-2.el6    @mysql56-community
mysql-community-devel.x86_64         5.6.19-2.el6    @mysql56-community
mysql-community-libs.x86_64          5.6.19-2.el6    @mysql56-community
mysql-community-server.x86_64        5.6.19-2.el6    @mysql56-community

$ find / -name libmysql*
/usr/lib64/mysql/libmysqlclient_r.so.18.1.0
/usr/lib64/mysql/libmysqlclient_r.a
/usr/lib64/mysql/libmysqlclient_r.so
/usr/lib64/mysql/libmysqlclient.so.18
/usr/lib64/mysql/libmysqlclient.a
/usr/lib64/mysql/libmysqlclient_r.so.18
/usr/lib64/mysql/libmysqlservices.a
/usr/lib64/mysql/libmysqlclient.so
/usr/lib64/mysql/libmysqlclient.so.18.1.0

$ php -r "phpinfo();" | grep "PDO"
PDO
PDO support => enabled
PDO drivers => mysql, sqlite
PDO Driver for MySQL, client library version => 5.6.19
PDO Driver for SQLite 3.x => enabled

こっちでは

# /etc/my.cnfの文字コード
character-set-server=utf8
skip-character-set-client-handshake #超だいじ

普通に文字化けしない環境の設定情報

$ cat /etc/redhat-release
CentOS release 6.5 (Final)

$ mysql --version
mysql Ver 14.14 Distrib 5.6.12, for Linux (x86_64) using EditLine wrapper

$ php -v
PHP 5.4.29 (cli) (built: Jun 5 2014 16:07:48)

$ yum list installed | grep mysql
mysql-libs.x86_64 5.5.32-1.el6.remi @remi
php-mysql.x86_64 5.4.29-3.el6.remi @remi

$ find / -name libmysql*
/usr/lib64/libmysqlclient_r.so.12
/usr/lib64/libmysqlclient_r.so.18.0.0
/usr/lib64/mysql/libmysqlclient_r.a
/usr/lib64/mysql/libmysqlservices.a
/usr/lib64/mysql/libmysqlclient.so.18
/usr/lib64/mysql/libmysqlclient.a
/usr/lib64/mysql/libmysqlclient.so.18.0.0
/usr/lib64/libmysqlclient.so.16
/usr/lib64/libmysqlclient.so
/usr/lib64/libmysqlclient.so.15.0.0
/usr/lib64/libmysqlclient_r.so.15
/usr/lib64/libmysqlclient_r.so.14
/usr/lib64/libmysqlclient_r.so.14.0.0
/usr/lib64/libmysqlclient_r.so.16.0.0
/usr/lib64/libmysqlclient.so.15
/usr/lib64/libmysqlclient_r.so.18
/usr/lib64/libmysqlclient_r.so
/usr/lib64/libmysqlclient.so.16.0.0
/usr/lib64/libmysqlclient_r.so.16
/usr/lib64/libmysqlclient.so.14.0.0
/usr/lib64/libmysqlclient.so.18
/usr/lib64/libmysqlclient_r.so.15.0.0
/usr/lib64/libmysqlclient.so.14
/usr/lib64/libmysqlclient.so.12.0.0
/usr/lib64/libmysqlclient.so.18.0.0
/usr/lib64/libmysqlclient_r.so.12.0.0
/usr/lib64/libmysqlclient.so.12

$ php -r "phpinfo();" | grep "PDO"
PDO
PDO support => enabled
PDO drivers => mysql, sqlite
PDO Driver for MySQL => enabled
PDO Driver for SQLite 3.x => enabled

PDO Driver for MySQL => enabled…? でも動いているんですよねー…。 ↓ ↓ ↓

# /etc/my.cnfの文字コード
character-set-server = utf8

ちなみに、両方ともMySQL Workbenchやコマンドラインから見るとこうなんだけど
mysql> show variables like "%character%";
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
文字化けするほうをPHP通して出力すると以下のようになってました。
character_set_client | <strong>latin1</strong>
character_set_connection | <strong>latin1</strong>
character_set_database | utf8
character_set_filesystem | binary
character_set_results | <strong>latin1</strong>
character_set_server | utf8
character_set_system | utf8
character_sets_dir | /usr/share/mysql/charsets/

//化けた文字をmb_detect_encodingしたもの
index.php#37string(8) "SJIS-win"

インストールしたときにシステムのタイムゾーンUTCだったのとかが関係あるのだろうか。
(途中から/usr/share/zoneinfo/Japanや、/usr/share/zoneinfo/Asia/Tokyoに変更したりした)

やれやれだぜ。

windows8.1にvagrantでCentOS6.4+php4+mysql4を作った

目的

Windows8.1(あえて64bitと明記)でvagrantでテストサーバを立てる。
都合上、php4/mysql4/apache2で構成。

用意するもの

vagrant 1.3.5(最新)
VirtualBox 4.2
現在4.3が最新ですが、Windows系64bitではVirtualBox Host-Only Ethernet Adapterがインストールできず積みます。(積みました)
ソースはここ→ https://github.com/mitchellh/vagrant/issues/2392
お好みのboxファイル
今回は http://www.vagrantbox.es から CentOS 6.4のminimalなものを探して、
https://github.com/2creatives/vagrant-centos/releases/tag/v0.1.0 構成のものを拝借。
Windows Powershell
これはお好み。コピペとサイズ変更が可能なDOS窓がほしかったんや。

やること

VirtualBoxをインストール

ダブルクリックのみ

vagrantをインストール

ダブルクリックしてインストール→再起動後、vagrant upまで。

> vagrant add box CentOS6_4 https://github.com/2creatives/vagrant-centos/releases/download/v0.1.0/centos64-x86_64-20131030.box

> mkdir CentOS6_4_php4_mysql4
> vagrant init

CentOS6_4_php4_mysql4/Vagrantfileを開いて

#書き換え
config.vm.box = &quot;base&quot;

↓ ↓

config.vm.box = &quot;CentOS_6_4&quot;

#以下は追記

config.vm.boot_timeout=60

保存したら

> vagrant up

結構待つ。

起動したら、以下の作業はすべてbox内。

> vagrant ssh

httpdほかインストール

sudo基本なので省略。

$ yum -y install httpd-devel bzip2-devel openssl-devel libjpeg-devel libpng-devel gmp-devel ncurses-devel flex gcc make

mysql4のインストール

sudo基本なので省略。

#php5用のmysql-libsが入っていて邪魔なので削除
$ yum remove mysql-libs

#perl-DBIがなくてインストールできないので先に入れる
$ yum install perl-DBI

#mysql4を入れる(チョイスはなんとなく)
$ wget ftp://ftp.pbone.net/mirror/mirror.cheetaweb.com/MySQL/4.0/MySQL-server-4.0.24-0.x86_64.rpm
$ wget ftp://ftp.pbone.net/mirror/mirror.cheetaweb.com/MySQL/4.0/MySQL-client-4.0.24-0.x86_64.rpm
$ wget ftp://ftp.pbone.net/mirror/mirror.cheetaweb.com/MySQL/4.0/MySQL-devel-4.0.24-0.x86_64.rpm
$ wget ftp://ftp.pbone.net/mirror/mirror.cheetaweb.com/MySQL/4.0/MySQL-share-4.0.24-0.x86_64.rpm

#順番に実行する
$ rpm -ivh ftp://ftp.pbone.net/mirror/mirror.cheetaweb.com/MySQL/4.0/MySQL-server-4.0.24-0.x86_64.rpm
$ rpm -ivh ftp://ftp.pbone.net/mirror/mirror.cheetaweb.com/MySQL/4.0/MySQL-client-4.0.24-0.x86_64.rpm
$ rpm -ivh ftp://ftp.pbone.net/mirror/mirror.cheetaweb.com/MySQL/4.0/MySQL-devel-4.0.24-0.x86_64.rpm
$ rpm -ivh ftp://ftp.pbone.net/mirror/mirror.cheetaweb.com/MySQL/4.0/MySQL-share-4.0.24-0.x86_64.rpm

順番に実行する。

すんなり入る。

設定ファイルはfindして、所定の位置にコピーする

$ sudo find / -name &quot;*my*cnf&quot;
$ sudo cp /usr/share/mysql/my-medium.cnf /etc/my.cnf

文字コードの設定など。

php4のインストール

sudo基本なの(ry

configure直前まではこちらのサイト通り。

CentOS6でphp4とphp5を共存させる
(openssl.soの流れも行う)

configreオプションは

$ ./configure
 --prefix=/usr/local/php4
 --with-apxs2=/usr/sbin/apxs
 --with-mysql
 --with-gd
 --with-jpeg-dir=/usr
 --with-png-dir=/usr
 --with-zlib
 --with-bz2
 --with-openssl
 --with-gettext
 --with-gmp
 --with-iconv
 --with-ncurses
 --enable-exif
 --enable-gd-native-ttf
 --enable-memory-limit
 --enable-mbstring
 --enable-mbstr-enc-trans
 --enable-bcmath
 --enable-trans-sid
 --enable-sysvsem
 --enable-sysvshm

–enable-mbregex(これが原因でmakeコケる、たぶん使わない)と–with-sqlite(今回は使わない)を削除した。

※なお、makeまで進んでコケたときは、configre再実行前に

$ make distclean

する。

$ make

$ make install

ここから先も、前述のサイトの通りhttpd.confの書き換え、AddHandlerも行う。

php.iniの設定も忘れずに。

そのあとは

vagrant sshを抜けて、CentOS6_4_php4_mysql4/Vagrantfileを開いて

#行頭の#をとる
config.vm.network :private_network, ip: "192.168.33.10"

保存したらコンソールに戻って

> vagrant reload

httpd、mysqlの起動設定とかもろもろやって、動作確認が取れたら

> vagrant package

で、もう二度とこの面倒くさいことをせずとも、同じ環境がpackage.boxから復帰できるようになります。

めでたしめでたし。

余談

phpからmysqlに接続するときに/tmp/mysql.sock関連のエラーが出たら、mysql起動しているかどうか確認して、起きているならmy.cnfの

socket = /var/lib/mysql/mysql.sock
socket = /tmp/mysql.sock

とする。

「Client does not support authentication protocol」エラーが出たら、
こちらを参考に http://d.hatena.ne.jp/psquare/20061207/p1 なんか腑に落ちないけどテスト環境だからまあいいかな処理を施す。

Windows7×JenkinsでAntで各種PEARが動かせない場合

本来は環境変数周りの問題だと思うのだけどあきらめた…

Antは使わずにcmdへコマンド投げる方法に切り替え

本来こうしたい所を

<target name="phpcpd" description="Find duplicate code using PHPCPD">
 <exec executable="phpcpd">
  <arg value="--log-pmd"/>
  <arg value="${basedir}/build/logs/pmd-cpd.xml"/>
  <arg path="${basedir}/src"/>
 </exec>
</target>

↓ ↓ ↓ cmdへ投げる形へ。

<target name="phpcpd" description="Find duplicate code using PHPCPD">
 <exec executable="cmd">
 <arg value="/c phpcpd --log-pmd ${basedir}/build/logs/pmd-cpd.xml ${basedir}/src" />
 </exec>
</target>

phpcpdでネストエラーが出てしまったら

phpcpdの仕様と前提となる環境がかみ合わないせいか、PHP5.4.3/PHP5.3.13で再現確認。

Fatal error: Maximum function nesting level of '100' reached, aborting! in C:\php\php5\pear\SebastianBergmann\Version\Version.php on line 125

Call Stack:
 0.0008 232488 1. {main}() C:\php\php5\phpcpd:0
 0.0102 632032 2. SebastianBergmann\PHPCPD\TextUI\Command->__construct(
) C:\php\php5\phpcpd:55
 0.0107 653600 3. SebastianBergmann\Version->getVersion() C:\p
hp\php5\pear\SebastianBergmann\PHPCPD\TextUI\Command.php:68
 0.0107 653824 4. SebastianBergmann\Version->getGitInformation() C:\wam
p\bin\php\php5\pear\SebastianBergmann\Version\Version.php:81
 0.0107 653904 5. SebastianBergmann\Version->isGitRepository() C:\wamp\
bin\php\php5\pear\SebastianBergmann\Version\Version.php:103
 0.0108 654104 6. SebastianBergmann\Version->isGitRepository() C:\wamp\
bin\php\php5\pear\SebastianBergmann\Version\Version.php:135
 0.0108 654224 7. SebastianBergmann\Version->isGitRepository() C:\wamp\
bin\php\php5\pear\SebastianBergmann\Version\Version.php:135
(以下延々)

PEARインストール先の問題のファイルを改変。
(gitリポジトリ内で呼ばれたら、最新のものを取ってくる判定をする部分なので挙動には支障ないはず)

例) C:\php\php5\pear\SebastianBergmann\Version\Version.php

//123行目付近
private function isGitRepository($path){
 return false; //動かないのだから仕方あるまい
...

今回調べ物してて思ったこと

Windows環境のオマケ扱いが加速している…。
Linux(Mac)表記が先で、Windowsの表記は「テストして無いけどこんな感じでしょ」みたいな書き方されてました。

Macを好きにならなければこの先苦労するのかもしれません。

WordPressショートコードで投稿データ表示。

テンプレート面倒くさくていじりたくない…。
新しいテンプレート作るときコピペするの面倒だもの…。

そこで、今更感抜群のこちら!

ショートコード内でテンプレートと同じ記事のループ処理をしてるので、
投稿内容がthe_content()とかdo_shortcode(get_the_content())を通ると記事が表示できます。

使い方としては、Magic Fields2プラグインでpost_typeとcustom_taxonomyいっぱい作って、
管理画面の編集できる範囲を固定化した後に、ページの本文でこのショートコードを呼び出して
一部の必要な記事を表示する。

ショートコード外の装飾はビジュアルエディタである程度いじれるのがメリット。

[show_posts post_type="posts" length="1"]

とかで管理画面から特定ポストタイプの最新の投稿1件を出せます。
あと、taxonomyも1個だけ対応している。
(ある固定ページにポストタイプ「event」の「交流会」タクソノミーの最新1件だけを表示したいときとかに)

[show_posts post_type="posts" taxonomy="post-tax"]

中ではWP_Queryでテンプレートに書くループやってるだけなので、後はスタイルシートで頑張る。

あと、ページ送りとか使わないような1件抽出とか向きです。そのへんまったく考慮してません。

あっ、中でloopテンプレート呼んだりしたほうがいいのかな?

<?php
function shortcode_show_posts($atts, $content = null){
 $result="";
//ショートコードで使えるオプションたち
 extract(shortcode_atts(array(
 'post_type'=>'',//ポストタイプ
 'post_id'=>'',//ポストID
 'length'=>1,//=posts_per_pages、記事数
 'taxonomy'=>'',//タクソノミー
 'order'=>'date',//ソート基準
 'orderby'=>'DESC',//ソート順
 'show_post_title'=>1,//タイトル表示するか?
 'show_post_date'=>1,//日付表示するか?
 'show_post_body'=>1,//本文表示するか?
 'use_link'=>0,//タイトルにパーマリンクするか?
 'title_class' => '',//タイトルに追加CSSクラス
 'body_class' => ''),//本文に追加CSSクラス
 $atts));

//WP_Queryに渡すオプションを整理
 if(!empty($taxonomy)){
//taxonomyがあるときは大体他の条件無視する。
 $opt=array(
 'tax_query'=>array(array('taxonomy'=>$post_type.'s', field=>'slug', terms=>array($taxonomy))),
 'posts_per_page'=>$length,
 'order'=>$order,
 'orderby'=>$orderby,
 'post_status' => 'publish'
 );
 }else{
 $opt=array(
 'post_type' => $post_type,
 'p'=>$post_id,
 'posts_per_page'=>$length,
 'order'=>$order,
 'orderby'=>$orderby,
 'post_status' => 'publish'
 );
 }

 $query = new WP_Query($opt);

 if($query->have_posts()):while($query->have_posts()):
 $result.='<div>';
 $query->the_post();

 if($show_post_title){
 $result.='<h3>';
 if($use_link){
 $result.='<a href="'.get_permalink().'">'.get_the_title().'</a>';
 }else{
 $result.=get_the_title();
 }
 $result.='</h3>';
 }

 if($show_post_date){
 $result.='<date>';
 $result.=get_the_date('Y年m月d日 H:i 掲載');
 $result.='</date>';
 }

 if($show_post_body){
 $result.='<div>';
 $content=do_shortcode(get_the_content());
 $result.=str_replace("\n","<br />",$content);
 }

 $result.='</div>';
 $result.='</div>';
 endwhile;endif;

 return $result;
}
add_shortcode("show_posts", "shortcode_show_posts");
?>