default eye-catch image.

配列、配列演算、繰り返し

本日の素振り。 [arst_toc tag=\"h3\"] 配列 配列はArrayクラスのインスタンス。 a = Array.new(3) # [nil,nil,nil] b = Array.new(2,\"hoge\") # [\"hoge\",\"hoge\"] 配列は[]で表す。 a = [10,20,30] # [10,20,30] a[1] # 20 b = [20,true,\"hoge\"] # [10,true,\"hoge\"] b[2] # \"hoge\" b[3] # nil %記法で配列生成 配列の要素が文字列である場合に限って、%W、%wによって文字列を配列化できる。 デリミタは半角スペース、%Wでダブルクォート、%wでシングルクォート(なし)。 自動的にダブルクォート、シングルクォートで括るため、 文字列の配列を作るためにダブルクォート、シングルクォートで汚すことを防げる。 p = %W(hoge fuga) # [\"hoge\",\"fuga\"] q = %w(hoge fuga) # [\'hoge\',\'fuga\'] joinで配列結合 配列と配列を結合して新しい配列を作るのではなく、要素を文字列として結合する。 p = [100,200,300] # [100,200,300] p.join # \"100200300\" p.join(\"_\") # \"100_200_300\" 配列の生成 Array.new()を使うと同じオブジェクトを持つ配列を作れる。 要素分の変数が確保されるのではなく、指定した値を持つ変数が1つ確保されて並ぶ。 a = Array.new(2,\"hoge\") # [\"hoge\", \"hoge\"] a.object_id # 4032 b.object_id # 4032 a[0].replace(\'fuga\') # [\"fuga\", \"fuga\"] a.object_id # 4032 b.object_id # 4032 Array.new(){}だと要素数分の変数が確保されて並ぶ。 a = Array.new(2){\'hoge\'} # [\"hoge\", \"hoge\"] a[0].object_id # 4033 a[1].object_id # 4034 範囲外アクセス 配列の大きさを超えてアクセスしたとき、例外とならず、アクセスしたところまで配列が広がる。 最初の位置から作った最後の位置までnilで埋められる。 a = Array.new(3){\"hoge\"} # [\"hoge\",\"hoge\",\"hoge\"] a[5] = \"fuga\" # [\"hoge\",\"hoge\",\"hoge\",nil,nil,\"fuga\"] 負の添え字アクセス 何が何でもコード行を削減したい意思! 配列に負の添え字でアクセスすると\"末尾から数えた位置\"という意味になる。 a = [\"hoge1\", \"hoge2\", \"hoge3\"] # [\"hoge1\", \"hoge2\", \"hoge3\"] a[-1] # \"hoge3\" 配列のスライス phpのarray_slice()に相当するやつ。指定したインデックスから何個分というやつ。 a = [0, 1, 2, 3, 4, 5, 6] # [0, 1, 2, 3, 4, 5, 6] a[2,3] # [2, 3, 4] 以下のように指定したインデックスから何個分を置き換えられる。 a = [0, 1, 2, 3, 4, 5, 6] # [0, 1, 2, 3, 4, 5, 6] a[1,2] = \"hoge\" # [0, \"hoge\", 3, 4, 5, 6] b = [0, 1, 2, 3, 4, 5, 6] # [0, 1, 2, 3, 4, 5, 6] b[1,2] = \"hoge\", \"fuga\" # [0, \"hoge\",\"fuga\", 3, 4, 5, 6] c = [0, 1, 2, 3, 4, 5, 6] # [0, 1, 2, 3, 4, 5, 6] c[1,2] = \"hoge1\", \"hoge2\", \"hoge3\" # [0, \"hoge1\",\"hoge2\",\"hoge3\", 3, 4, 5, 6] 複数の戻り返却と多重代入 複数の値を返す関数を定義する。複数の値を返すように見えるが配列が返っている。 def test return \"hoge1\", \"hoge2\", \"hoge3\" end a, b, c = test # [\"hoge1\", \"hoge2\", \"hoge3\"] a # \"hoge1\" b # \"hoge2\" c $ \"hoge3\" 戻りとしてネストした配列を返すことができて、同じ構造の変数に代入できる。(多重代入) def test2 return [[\"hoge1\", \"hoge2\"], \"hoge3\"] end (x,y),z = test2 # [[\"hoge1\",\"hgoe2\"], \"hoge3\"] +、-演算子 左オペランドと右オペランドの要素の加算、左オペランドから右オペランドの減算 a = [\"hoge1\",\"hoge2\"] # [\"hoge1\",\"hoge2\"] b = [\"hoge2\",\"hoge3\"] # [\"hoge2\",\"hoge3\"] a + b # [\"hoge1\",\"hoge2\",\"hoge2\",\"hoge3\"] a - b # [\"hoge1\"] b - a # [\"hoge3\"] 減算の場合、左オペランドに重複があるときは全て削除される x = [\"hoge1\",\"hoge1\",\"hoge2\"] # [\"hoge1\",\"hoge2\",\"hoge3\"] y = [\"hoge1\"] x - y # [\"hoge2\",\"hoge3\"] *演算子 右オペランドが数値の場合は左オペランドをその回数繰り返す。 右オペランドが文字列の場合はjoinと同じ。 a = [1,2,3] a * 2 # [1,2,3,1,2,3] for式,each式 PHPのforeachに近いforとeach。forは期待と異なりループの中と外はスコープが同じ。 for内の変数をfor外でアクセスできる。 for value in [100,200,300] inner_loop = 500 end inner_loop + 100 # 600 対してeachはループ内とループ外でスコープが異なりeach内の変数はeach外で未初期化。 [100,200,300].each do inner_look2 = 500 end inner_loop # undefined variable

default eye-catch image.

symbol、参照、破壊的メソッド

[arst_toc tag=\"h3\"] シンボル 文字列そのものに意味はなく、単純にラベルとして文字列を扱いたいというときシンボルを使う。 シンボルのポイントは、文字の並びが同じであれば(同値であれば)同一であること。 hoge1 = :hoge1 p hoge1 # 524328 hoge2 = :hoge1 p hoge2 # 524328 hoge3 = :hoge3 p hoge3 # 324648 文字列からシンボルに変換できる。 hogeA = \"hoge1\".to_sym p hogeA.object_id # 524328 値の同値性と同一性 演算子==は、例えば2つの文字列の値が等しいかどうか(同値であるか)を比較する。 一方で、2つの変数のobject_idが等しいかどうか(同一であるか)を比較するために、 equal?メソッドを利用する。 hoge_x = \"hoge1\" hoge_y = \"hoge1\" p hoge_x == hoge_y # true p hoge_x.equal? hoge_y # false オブジェクトと参照 変数を宣言すると(つまりリテラルを指定すると)オブジェクトへの参照が与えられる。 以下の場合、\"hoge\"という一つのオブジェクトをhoge1、hoge2が参照する形になる。 hoge1 = \"hoge\" hoge2 = hoge1 hoge1.equal? hoge2 # true 片方の変数について値を変更した場合、その変更に対応するオブジェクトが新たに作られ、 新しいオブジェクトへの参照が作られる。 hoge1 = \"hoge\" hoge2 = hoge1 hoge2 = hoge2 + \"fuga\" p hoge1 # hoge p hoge2 # hogefuga hoge1.equal? hoge2 # false 実引数と仮引数の参照 関数に実引数として渡した変数と関数内で利用できる仮引数の参照は同じ。 ただし関数内で仮引数に対して処理すると、別の値が確保され、仮引数はその値への参照となる。 x = 100 x.object_id # 435123 def func x p x.object_id # 435123 x = 200 p x.object_id # 249821 end 破壊的メソッドと参照 変数の値を変更したときに参照を変えずに値を変更するメソッドを破壊的メソッドという。 慣例的に破壊的メソッドの末尾には「!」をつける。 破壊的メソッドと、代入時に別変数を確保して参照を変更するメソッドはしばしば同名で、 「!」により区別することがある。 残念ながら徹底されておらず、破壊的メソッドなのに「!」がなかったり逆もある。 w = \"hogehoge\" w.chop # \"hogehog\" w # \"hogehoge\" w.chop! # \"hogehog\" w # \"hogehog\"

default eye-catch image.

文字列、%記法

[arst_toc tag=\"h3\"] 文字列の式展開 PHPと同様にダブルクォート、シングルクォートにより文字列を表現する。 前者は変数展開あり、後者は変数展開なし。 実際には文字列内の\"式展開\"で、式のto_sメソッドの評価結果が文字列に展開される。 to_sメソッドを備えていれば独自クラスでも展開できる。 hoge = 10 p \"hoge is #{hoge}\" # hoge is 10 p \'hoge is #{hoge}\' # hoge is #{a} ただ文字列の中に変数を書いただけではダメで、変数展開用の識別子がいるんだな。 パーセント記法による式展開 シングルクォート、ダブルクォート以外を使って文字列を作ることもできる。 文字列の中でエスケープ無しでシングルクォート、ダブルクォートを使えて便利。 hoge = %*THIS IS TEST STRING \"HOGEHOGE\".*% もともとシングルクォート、ダブルクォートの区別により式展開するしないが決まっていたが、 当然パーセント記法を使うと式展開をそのままでは選べない。 パーセントの後にq、またはQを付与することで式展開をするしないを選ぶことができる。 なお、デフォルトは式展開をする。つまり%Qと同じ。 fuga = 100 %q*#{fuga + 100}* # \"#{fuga + 100}\" %Q*#{fuga + 100}* # \"200\" Rubyが複雑に見えるのはコイツのせいじゃないだろうか。 文字列の型変換 文字列から整数、浮動小数点、複素数、有理数などへ変換できる。 それぞれ、to_i、to_f、to_c、to_rというメソッドが用意されている。 厄介そうなことに、型変換ができない場合、変換できるところまで変換する。 そもそも先頭の文字が変換できないなら0。 \"100\".to_i # 100 \"10ab\".to_i # 10 \"1.1.1\".to_f # 1 \"hoge\".to_i # 0 デバッグ出力と関数 文字列をデバッグ用途に出力するときはpを使う。変数内の式は展開されない。 他に、print、putsで出力できる。こちらは変数内の式が展開される。 hoge = \"100 n\" p hoge # \"100 n\" puts 100 # 100 ヒアドキュメント 変数展開なしのヒアドキュメントは以下の通り。ヒアドキュメントの開始をシングルクォートにする。 ヒアドキュメントの終了は識別子も前にスペース禁止。 hoge = 100 str = <<'DOC' #{hoge} HOGE DOC 変数展開ありのヒアドキュメントは以下の通り。開始をダブルクォートにする。 hoge = 100 str = <<"DOC" #{hoge} HOGE DOC 文字列演算 文字列は+、*に対応している。 hoge = \"HOGE\" + \"FUGA\" # \"HOGEFUGA\" fuga = \"HOGE\" * 3 # \"HOGEHOGEHOGE\" <<により文字列連結。 hoge = \"HOGE\" hoge << "FUGA" # "HOGEFUGA" 比較演算 文字列の辞書順で比較する。 \"X\" \"Y\" # false \"XXX\" < "XXY" # true "XYZ" == "XYZ" # true 文字列長 .lengthメソッドにより文字列長を返す。バイト数ではなく文字数。 \"HOGEHOGE\".length # 8 sprintfと% %演算子にはsprintf相当の機能も備わっていて混乱する。 知らないと訳がわからない。 sprintf(\"THIS IS TEST INTEGER %02d\",1) # \"THIS IS TEST INTEGER 01\" p \"THIS IS TEST INTEGER %02d\" % 1 # THIS IS TEST INTEGER 01\"

default eye-catch image.

論理値、論理演算子、自己代入

真/偽 TrueClassのインスタンスがtrue、 FalseClassのインスタンスがfalse。 NilClassのインスタンスがnil。 true.class # TrueClass false.class # FalseClass falseとnilのみ偽として評価される。 falseとnil以外は全て真として評価。 この動きにより、変数に値が入っているかどうかは、 nilと比較する必要はなく変数を評価するだけで良い。 PHPのように変数に値が入っていることをチェックする必要はない。 if文 オーソドックスなif文。 compare = true if compare then \"OK\" end if文は式なのでif文を評価すると値が返る。 評価値はif式内で最後に評価された値となる。 a = if true 1 end p a # 1 後置ifという構文。簡単にコードが短くなって便利そう。だが...、 後置ifがfalseの場合でも、変数自体は確保される。が値が入らない。 意図せず変数がnilになるコードを書く可能性がある。 未定義の変数と、確保済みだが値なしの変数は明確に異なる。 a = 1 if true p a # 1 b = 1 if false p b # nil もし偽だったら、を書きたい場合はunless構文を使う。 unless false p 1 # 1 end 単項演算子?は使える。 n = (a==10) ? true : false 論理演算子 論理演算子は最後に評価したオペランドの値を返す。 評価結果(true,false)を返さない。 x = nil && 4 # nil y = 1 || 2 # 1 自己代入 変数が真でない場合に限りその変数に値を代入する自己代入。 これは、論理演算の際どい評価順序を利用していて、何故そうなるかは深い深い海の底にある。 z = z || 1 # 1 z ||= 1 # 1 zが真でない場合、つまりzがfalseかnilの場合に、 論理和演算子の右側のオペランドである1の評価結果(=1)がzに代入される。 未確保・未定義の変数の評価結果はnilなので、 未定義・未確保の場合に限り初期値を入れることができる。 z = 10 z = z || 1 # 10 &&とand、||とor、!とnot &&とand、||とor、!とnotという風に、同じ意味の論理演算子が対で用意されている。 それぞれ評価時の優先順位が異なる。(以下のようになる) p x && z # = p (x && z) p x and z # = (p x) and z

default eye-catch image.

整数リテラルとメソッド

[arst_toc tag=\"h3\"] 命名規則1.ローカル変数 変数名により用途が決まるので理解が必要。 資格系なら\"不適切な変数名\"を見抜けるかが大事。 ローカル変数は、代入が行われたブロックまたはメソッドの中だけで有効なスコープの変数。 ローカル変数は以下から構成される。ただし数字は先に来ない。 アンダースコア「_」 英数字 以下は変数名としてN.G. # アンダースコア以外の記号「-」が使われている variable-1 # これも safe? # 先頭が数値 100_or_1000 # 定数 VARIABLE 予約後を変数として再定義することはできない。 関数内ならスコープ外のローカル変数を参照すると例外。 kuma=20 def hoge(x,y) kuma end スコープ内で定義されているが評価されていない変数を参照するとnil。 def hoge(x,y) kuma = x + y if x > 10 kuma end > hoge 20,30 => 50 > hoge 5,10 => nil 命名規則2.グローバル変数 スコープに関係なくどこからでも参照できる変数。 構成する文字はローカル変数と同じ。ただし先頭は「$」。 アンダースコア「_」 英数字 $global = 100 def fuga(a,b) $global end > fuga 10,20 => 100 リテラルの種類 Rubyのリテラルは以下。 数値 論理値 文字列 シンボル 配列 ハッシュ 範囲 正規表現 ハッシュ 数値リテラル 整数と浮動小数点を使える。符号、指数表記、基数指定が可能。 基数指定でありえない値を指定すると例外。 +100 -200 2e2 # 2 に10の2乗を掛ける => 20 5e-e # 5 に10の-3乗を掛ける => 0.05 0b10 # 2進数の10 => 2 0o10 # 8進数の10 => 8 0d10 # 10進数の10 => 10 0x10 # 16進数の10 => 16 0xfg # 16進数でgはNG 数値リテラル内で桁表現ができる。(ロケールが違うときはどうなるのだろうか?) 100_000 => 100000 有理数(Rational)、複素数(Complex)もリテラル。 有理数は既約になる。浮動小数点にしないで保持できる。 また、小数を既約分数に変換できる!(すごい過剰な感じがする...) 25/45r # (5/9) 3.14r # (157/50) 複素数は実数、虚数の指定を整数、小数を使って表現できる。 12i # (0+12i) 5.6i # (5+6i) 有理数、虚数をミックスすることもできる。 3.14ri # (0+(157/50)i) 数値クラス 数値クラスのインスタンスである。 一言に数値クラスといっても継承関係によって詳細化されている。 a = 100 a.class # Fixnum a.class.superclass # Integer a.class.superclass.superclass # Numeric 数値クラスに実装された演算子により、数値演算、比較演算を実行できるようになっている。 数値演算 代表的な2項演算子は一通り使える。 1+1 # 2 1-2 # -1 3*3 # 9 4/2 # 2 4%3 # 1 代表的な比較演算子も一通り使える。 1==1 # true 1!=5 # true 1=1 # true 怪しい演算子が用意されている。UFO演算子。 演算子の左が大きければ1、等しければ0、右が大きければ-1。 500 10 # 1 500 500 # 0 10 500 # -1 と書いてあるけど、オペランドがNumericの時の話であって、 一般には「正」「0」「負」の振り分けと考えた方が良さそう。 オペランドが比較不能な場合はnilだそうだ。 if文を使って3方分岐するときに使える。 compare = (hoge fuga) if compare == 0 # hogeとfugaが比較可能で等しいとき elseif compare > 0 # hogeとfugaが比較可能でhogeが大きいとき else # 上記以外 (比較可能でfugaが大きいときを含む) end Rubyにはインクリメント演算子、デクリメント演算子は存在しない。 ので代わりに自己代入演算子を使う。 a = 100 a += 20 # 120 a -= 30 # 90 a *= 2 # 180 数値クラスの演算子であることを意識した書き方をすると、 数値の加算を以下のように書ける。 a = 100 a .+(50) # 150 メソッド 最後に評価された値が返る。returnで返すとそこで評価が終了する。 returnを書かないと関数内を最後まで読んで何が最終評価か理解しないといけないから 明示的returnを推奨する人もいるが、無いコードも多数ある。資格系はreturn無しの様子。 def add(x,y) x+y end > add 10,20 30=> nil def predict(hoge) if (hoge) then \"OK\" else \"NG\" end end > predict false => \"NG\" 仮引数のデフォルト値を指定できる。指定した引数の数が足りない場合は例外。 def add(x,y=200) x+y end add 10 => 210 キーワード引数 仮引数に名前をつけることができる。 これによりメソッド実行時に引数としてハッシュオブジェクトを渡せるようになる。 def add(x:,y:) x+y end add (x:100,y:200) => 300 キーワード引数にない引数名を指定すると例外。 def add(x:,y:) x+y end add (x:100,z:200) # 例外 ただし、キーワード引数を定義したメソッドに任意の引数を渡すことができる。 def add(x:,y:,**z) p z x+y end add (x:100,y:200,z:300) # {z=>300} => 300

default eye-catch image.

vagrant(ubuntu/xenial64 vbox) ubuntu16にrbenv rubyをインストールするplaybook (ほぼ失敗作)

作ってみたがrbenv installにとても時間がかかるので現実的ではないと思う。 vagrantのように壊して作るのが前提ならrbenvでバージョンを切り替えられる必要はないから、 わざわざ毎回コンパイルすることはない気がする。 いずれapt-get installで直接インストールする方法を試してみる。 commonロール 実験の結果、ubuntu/xenial64 vboxに必要だったパッケージたちを入れるロール。 become: yes, become_method: sudo で実行。 --- - name: install packages apt: name=\"{{item}}\" state=present with_items: - gcc - make - libssl-dev - zlib1g-dev rbenv,rubyインストールロール ansible実行ユーザ(ubuntu)のホームディレクトリ以下にrbenvとrubyを入れるロール。 .profileに追加した内容を反映して次に進まないとエラーになる...->要改良 --- - name: retrieve the latest rbenv to ~/.rbenv git: repo=https://github.com/sstephenson/rbenv.git dest=/home/{{user}}/.rbenv accept_hostkey=yes force=yes - name: retrieve the latest ruby-build plugin to ~/.rbenv/plugins/ruby-build git: repo=git://github.com/sstephenson/ruby-build.git dest=/home/{{user}}/.rbenv/plugins/ruby-build accept_hostkey=yes force=yes - name: add path to ~/.rbenv/bin lineinfile: dest=/home/{{user}}/.profile line=\'PATH=\"$HOME/.rbenv/bin:$PATH\"\' state=present create=yes - name: add path to ~/.rbenv/plugins/ruby-build/bin lineinfile: dest=/home/{{user}}/.profile line=\'PATH=\"$HOME/.rbenv/plugins/ruby-build/bin:$PATH\"\' state=present create=yes - name: add initial evaluation of rbenv init lineinfile: dest=/home/{{user}}/.profile line=\'eval \"$(rbenv init -)\"\' state=present create=yes - name: add gem lineinfile: dest=/home/{{user}}/.gemrc line=\"gem{{COLON}} --no-ri --no-rdoc\" state=present create=yes - name: rbenv install 2.4.1 shell: bash -lc \"rbenv install 2.4.1\" - name: rbenv global 2.4.1 shell: bash -lc \"rbenv global 2.4.1\" - name: gem install bundler shell: bash -lc \"gem install bundler\"

default eye-catch image.

FileMakerServer16/17に非公式SSL/TLS証明書をインストールする

はじめに オンプレミスでFileMakerServerを配置するのではなく、AWS,Azure,さくらクラウドなどに配置することが増えているためか、FileMakerServerにSSL/TLS証明書をインストールしたいという要望が増えていそうです。 FileMaker社はFMS15,16用に利用可能なSSL/TLS証明書を公開していますが[1]、どれもアメリカ本国の業者であるだけでなく、いわゆる格安証明書がリストされておらず、たかだかイントラ用のアプリのために高額なお布施を積まないといけない状況にあります。 FileMaker社はFMS17用に利用可能なSSL/TLS証明書に関する記述を改めましたが[2]、いずれにせよ、適合するか否かは実験してみる必要があります。 適合しない証明書をインストールすると、「通信は暗号化されているか証明書を検証できない」というおかしな状況が出来上がります[3]。もともとClosedな傾向が強いFileMakerですが、この状況がどういう理由で発生しているのか確認する術がなく、発生してしまった場合に解決が非常に困難です。 日本の格安SSL/TLS証明書をFMS15,16,17にインストールすることができましたので、 本記事ではその事実を紹介します。 まず結論 以下の証明書をFMS15,16,17にインストールできました。 「鍵マーク」は緑色となります。 さくらインターネットのRapidSSL(DV証明書) 1,620円/年 中間CA証明書必須 クロスルート証明書必須 AWS EC2上 WindowsServer2012 R2 (JPN) または Azure上のWindowsServer2012 R2(JPN) IISでファイル認証 OS、プラットフォーム、Webサーバはオプションです。他でもOKなはずです。 格安証明書で有名なSSLストアはRapidSSLのファイル認証をやめてしまったので、 RapidSSLをファイル認証で取得できるのはここだけかもしれません。 SSLストアのFujiSSL、ComodoSSL(PositiveSSL)はいずれも入りませんでした。 中間CA証明書、クロスルート証明書がないと、証明書自体のインストールは出来ますが、鍵が「オレンジ色」になります。FMSは中間CA証明書、クロスルート証明書を見ています。 なお、FMSには中間証明書を指定するUIが一つしかありませんので、FileMaker社が指定する方法で中間CA証明書、クロスルート証明書を結合する必要があります。 以下の通り結合し1つのファイルとしておきます。 -----BEGIN CERTIFICATE----- Root certificate -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- Intermediate certificate 2 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- Intermediate certificate 1 -----END CERTIFICATE-----

default eye-catch image.

非マルチサイトでユーザ情報を共有する

概要 ネットワーク機能経由のマルチサイトでなく、サブディレクトリ型マルチサイトでもなく、 単純にサブディレクトリに複数のWordPressインスタンスを並列するケースで、 複数のWordPressインスタンスから一つのユーザ情報を共有する方法について書く。 wp_users,wp_usermetaの共有 このあたりを参照すると書いてある。要は、インスタンスの数だけ作られるwp_users、wp_usermetaを使わず、一つを共有すれば良い。そのためにはwp-config.phpを修正すれば良い。ただしWordPressの互換性的な都合を理解しておく必要がある。 カスタム User テーブルとカスタム Usermeta テーブル CUSTOM_USER_TABLE および CUSTOM_USER_META_TABLE を使用すると、通常 WordPress が利用する user および usermeta テーブルを使用せず、代わりに指定されたテーブル名を使用してユーザー情報を格納します。 define( \'CUSTOM_USER_TABLE\', $table_prefix.\'my_users\' ); define( \'CUSTOM_USER_META_TABLE\', $table_prefix.\'my_usermeta\' ); WordPressは互換性確保のためwp_usersの拡張を推奨しておらず、wp_usermetaに拡張情報を持たせることになっている。拡張情報をwp_usersのカラムとして持たないことで、拡張が必要になったときに初めてwp_usermetaにレコードが作られる。つまり、wp_usermetaはインスタンス毎の拡張情報であるということ。 そのため、CUSTOM_USER_TABLE、CUSTOM_USER_META_TABLEを指定したとしても、共有しようとしたwp_users、wp_usermetaとは別にインスタンス毎にwp_users,wp_usermetaテーブルが作られる。 インスタンスのインストール時にID=1番のレコードが作られる。インスタンスの最初の管理者はこのレコードである。wp_usersのID=1はSuperAdmin的な特別なアカウントで、各インスタンスのwp_users,wp_usermetaが使われる。 共有しようとするwp_usersには、インストールしたインスタンス用のwp_usermetaが無いので「権限なし」となる。そこで、まず、各インスタンスに作られてしまったID=1でログインし、次に共有するwp_usersテーブルのアカウントにインスタンス毎の権限を付与することで解決する。 面倒だけど、確かにアカウントの互換性は保たれるな。

default eye-catch image.

FileMakerServer15の通信を無料でSSL化する方法

FileMakerServer15からデータベースの公開に関してセキュリティが考えられるようになった(本気になった感じ)。Windows VPSにFileMakerServerを配置することでお手軽クラウドが完成するので、割と重要なアップデートだと思う。 Rapid SSLは無理 CSRを作成し、証明書に署名してもらって、秘密鍵と一緒にサーバにインストールする流れはWebサーバと同じだが、RapidSSLなどドメイン認証式(かつファイル認証式)の証明書を作成する場合、FMSは80番で待っている訳ではないから「DocumentRootにファイルを配置してクロールしてもらう」という手続きを進められない。 じゃあ、簡易httpdを立てたらどうか。 RapidSSLのサイトには以下のような記述がある。 RapidSSL、PositiveSSLをお申込みの方へ ホームページが未完成、ホームページに運営者情報が掲載されていない場合、会員制など、ログインが必要なホームページの場合、審査を通過しないケースが増えております。 仮のWebサーバを立てて80番を開けてファイルを配置しても、そもそも怪しい署名リクエストはリジェクトされちゃうらしい!とりあえず、1日経っても来なかった。 一般的なフローではないのだから、仕方ないんじゃないかな。と納得する。そして無料SSLに触手を伸ばす。 Linuxであれば、Certbotを使って90日間の証明書を発行すれば良いが、2017年3月現在、WindowsServerで動作するCertbotが存在せず、Certbotは利用できなさそうである。Windows Serverにvagrant/virtualboxを立てて80番をそこに通すというやり方を思いついたが、それは相当に面倒くさい。 Zero SSL 世の中には便利なサービスがあるものだ。Certbot認証局側をやってくれるサービスが存在する。Zero SSLだ。手順はここのサイトが詳しかった。 サービスのWizardに従ってCSRとコモンネーム(ドメイン)を入力すると、サーバの80の指定URLにファイルを置いてくれ、と言われる。Wizardに従ってNextボタンを押下し続ければ、画面に署名済み証明書と中間証明書が表示される。 FMS15側で1)証明書、2)プライベートキー、3)中間証明書を入れてくれ、と言われるが、2)のプライベートキーはFMS15で生成したものをいれる。ZeroSSLで生成されるプライベートキーは利用しない。1),2),3)を安全な場所に保管しておくこと。 肝心のポート番号だが、80を閉じても繋がるようになった。しかし、443以外のwell knownでないFileMaker専用ポートは依然として使われるようだ。SSLをトンネルとして使うという訳ではなさそうだ。

default eye-catch image.

Laravel Mutator Accessor

たぶん Delphi/C# が起源だと思うんだが、データに紐づく規則や処理をモデルに寄せるパターン(Microsoft:The Repository Pattern)と同等の機能がPHP FrameworkであるLaravelのORM(Eloquent)にあり、流石に超便利だったのでメモっておく。 setter側をMutator、getter側をAccessorという。Mutator, Accessorを簡単にまとめると以下のような感じ。 Eloquentインスタンスに対して値をセットする際に必ずあるメソッド(Mutator)を経由する機能 Eloquentインスタンスから値をゲットする際に必ずあるメソッド(Accessor)を経由する機能 本家のドキュメントは以下のように続く。 Accessors and mutators allow you to format Eloquent attribute values when you retrieve or set them on model instances. For example, you may want to use the Laravel encrypter to encrypt a value while it is stored in the database, and then automatically decrypt the attribute when you access it on an Eloquent model. データに紐づくルールや処理をモデルに寄せることでコントローラの肥大化を防ぐ機能の一つだが、コントローラとモデルの間の取り決めを規約によって定めることで、コントローラからもモデルからも扱いやすくなる。 例えば、usersテーブルにfirst_nameという名前のフィールドがあったとする。 フィールドには小文字で入力し、使うときは必ず先頭1文字を大文字として使う、というルールがある場合Userモデル側を以下のような規約に従って書く。 <?php namespace App; use IlluminateDatabaseEloquentModel; class User extends Model { /* * Get the user\'s first name. * * @param string $value * @return string */ public function getFirstNameAttribute($value) { return ucfirst($value); } /* * Set the user\'s first name. * * @param string $value * @return void */ public function setFirstNameAttribute($value) { $this->attributes[\'first_name\'] = strtolower($value); } } コントローラからfirst_nameフィールドの値を取るコードは以下の通りだが、必ずAccessorを経由し値が返る。フィールドの値が何であれ先頭は必ず大文字になる。ブラウザ等に表示する際に加工する必要がない。 <?php $user = AppUser::find(1); $firstname = $user->first_name; ブラウザ等からデータが入って来たとき、それをusers.first_nameフィールドに格納する処理を書く際、必ずMutatorを経由する。 「小文字にする」という処理を一切意識しないで良い。 <?php $user = AppUser::find(1); $user->first_name = \'Sally\'; コントローラより上は涼しい顔をして重い処理の記述を省略できる。データに紐づくルールが重ければ重いほどモデルに寄せる効果が大きくなる。 例えば、データを暗号化して格納するケースにおいては、暗号化/復号処理をModelに隠蔽しControllerより上からは透過的に平文として扱うなど。 Eloquentは流石に雄弁だ。