hagetak's blog

どうも、はげたかです。

アップロードされたファイルをどこまでバリデーションするか(PHP)

アップロードされたファイルをどこまでバリデーションするか(PHP

概要

CakePHP1.3プロジェクト で、アップロードされたファイルを加工する必要があった。その際、アップロードされたものをどこまでバリデーションを行うか、が問題である。

ここが長すぎたら Controller が肥大化し( ValidationClass を作っても良いが)、 簡単なバリデーションだといつか痛い目にあう。

スクリプト

簡易的ではあるが、僕は以下のようにバリデーションを行う.

class AdminController {

    /**
     * アップロードファイル([].csv)を受け取る.
     * @return 
     */
    public upload_file()
    {
        // POST 以外は受け付けない(cake1.3)
        if (empty($this->data)) {
            echo 'POST ではありません.';
            return false;
        }

        // 変数が存在しているか確認.
        // これを抜きにすると, `is_uploaded_file()` で Warning が発生
        if ( !isset($data['ThisModel']['row_file']['tmp_name']) || !isset($data['ThisModel']['row_file']['name'])) {
            echo 'ファイルが見つかりません.';
            return;
        } 

        // アップロードファイルか確認
        if ( !is_uploaded_file($data['ThisModel']['row_file']['tmp_name'])) {
            echo '不正なアップロードです.';
            return;
        }

        // アップロードファイルをゴニョゴニョ
        $uploaded_fp = fopen($this->data['ThisModel']['row_file' ]['tmp_name'], 'r');
    }
}

良いアイディアが有りましたら、コメント頂けると幸いです。

メタプログラミングとは - Rubyを例に説明

[メタプログラミング]最近良く聞く、メタプログラミングとは

最近、メタプログラミングという言葉をよく聞く。といっても、結構前からだが、意識し始めたのは最近。

メタってなんだよ、メタってと思っていた時期がありましたが、ようやくなんぞやと調べる気になった。

ruby の技術力を少しずつ上げていきたいので、ruby を例に説明する。

メタプログラミングとは

meta_programming_08.rb

class Rabbit
  class << self
    def colors
      [:black, :brown, :white, :mixed]
    end
  end
end
 
p Rabbit.colors

また、クラスメソッドを定義することは、現場のコードでしばしば見られるパターンなのに、> 実際は複雑であることも理由の一つです。Ruby初心者からすると、「class << self」のよう> なコードを見たら、ギョッとすることでしょう(私もそうでした)。

コンパイルなしに実行できる

ゲッターとセッターを自動生成

いくつものインスタンス変数があり、それぞれにゲッター/セッターを定義するのは面倒である

そこで、このメタプログラミングを用いて、(実行時に)自動生成させる

class Item
    def get_price
        @price
    end
    def set_price v
        @price = v    
    end

    def get_name
        @name
    end
    def set_name v
        @name = v        
    end
    # インスタンス変数の数だけセッターとゲッターが存在する
end
class Item
    def define_accessor *plist
        self.class.class_eval do
            plist.each do | property|
                define_method "get_#{property}" do
                    @property
                end
                define_method "set_#{property}" do |v|
                    @property = v
                end
            end
        end
    end
end

item = Item.new
item.define_accessor "price", "name", "category"
item.methods.grep(:get_price)

個人的にこれはよく書けたな、と自画自賛をしたいところだが、ネストが深い。

さいごに

ざっくりメタプログラミングというものを知った。動的にメソッドを追加することなのかな。初見では、メリットが分かりづらかったが、セッター・ゲッターの例から少し便利さを知ることができた。

こうしたほうが Ruby っぽい。こうしたほうが綺麗。テクニックなど、教えて下さい。

メタプログラミングRuby 第2版

メタプログラミングRuby 第2版

冪等性(べきとうせい)とは

冪等性(べきとうせい)とは

ココ1年くらいで、冪等性(べきとうせい)という言葉を何度も聞いた。 ついに業務でもこの言葉が出てきたので、改めて意味を調べてみることにする。

冪等性とは

冪等性とは、ある操作を1回行っても複数回行っても結果が同じであることをいう概念である。

よく例にあげられるのは、i = 0i = i + 1 である。

var i = 0; // i は必ず 0 になる:冪等性が保たれる


// 実行する度に i が 1 足される。(実行回数によって、 i の値が変わってしまう)
// :冪等性が保たれない
i = i + 1 

他に例を挙げるなら、 copy も同様である。

copy a.txt b.txt # copy できた

copy a.txt b.txt # 既に b.txt があるため、copy できない overwrite b.txt? (y/n [n])

インフラと冪等性

この概念をインフラ構成に組み込んだのが、ChefAnsible などである。 システムの機能を変更するなら、サーバーをぶっ壊して、新しく作りなおすというものである。

サーバに nginx がインストールされていれば、繰り返しインストールすると、エラーが返ってくる

を何度実行しても Nginx がインストールされて起動した状態に収束し、何回も繰り返しインストールされたり、既にインストールされているからといってエラーになったりすることはありません。
ほとんどの場合、 Chef の動作は冪等性が保証されていますが、 Script や Execute などの DSL は書き方によっては冪等性が保証されないことがあります。
ですのでレシピを書く際は冪等性が保証されるように意識的に作り込んでください。

from: http://blog.schoolwith.me/chef-re-introduction/

REST と冪等性

  • GET

/show/1

API の種類にもよるが)これは、必ず ID の値が 1 のデータが返ってくる。 何度も、show/1 にリクエストを送っても、 1 のデータが返ってくる。

  • DELETE

/delete/1

id が 1 であるデータが削除される。これも冪等性が保たれる。

おわかりだろうか。

冪等とは「ある操作を何回行っても結果が同じこと」を意味する数学用語です。たとえばPUTとDELETEは冪等ですので、PUTやDELETEを同じリソースに何回発行しても、必ず同じ結果(リソースの内容が更新されている、リソースが削除されている)が得られます。
安全とは「操作対象のリソースの状態を変化させないこと」を意味します。リソースの状態に変化を与えることを副作用といいますので、安全は「操作対象のリソースに副作用がないこと」とも言います。たとえばGETには副作用がないので、GETを同じリソースに何回発行してもリソースの状態は変化しません。

http://blog.ruedap.com/2011/03/25/http-method-post-put-idempotence

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

実践編

http://blog.schoolwith.me/chef-re-introduction/

さいごに

冪等性。冪等性を理解するのは、難しい。実際に AnsibleChef を使ってみることで、有り難みが理解できるのかな。

Chef実践入門 ~コードによるインフラ構成の自動化 (WEB+DB PRESS plus)

Chef実践入門 ~コードによるインフラ構成の自動化 (WEB+DB PRESS plus)

PHPで時刻の範囲内で処理を行う。

はじめに

卒業制作をしていて、証券取引所の取引可能時間内(9:00 - 15:00)で取引が行うようにする必要があった。 範囲内で作業を分けるようなTipsがなかったの、執筆してみる。

コード

<?php

// date('Y-m-d **:**:**') で範囲を設定する
$start_date = date('Y-m-d 9:00:00');
$end_date = date('Y-m-d 15:00:00');
$today = date('Y-m-d h:m:i');

// 計算できるようにミリ秒にする
$start_time = strtotime($start_date);
$end_time = strtotime($end_date);
$today_time = strtotime($today);

if($start_time <= $today_time && $today_time <= $end_time){
  // start_date <= today <= $end_date
  echo 'inner';
} else {
  // !start_date <= today <= $end_date
  echo 'outer';
}

パーフェクトPHP

パーフェクトPHP

プログラミングPHP 第3版

プログラミングPHP 第3版

【Github】vagrant から push したら別のユーザ名が出現した

お久しぶりです。

Github(今回は、Bitbucket)にVagrant から push したら別のユーザ名でcommit されていた。 (例:vagrant, root)

これでは誰かわからないため、vagrant の方のユーザに、名前をつけることにする。

$ git config user.name "my_new_name" $ git config user.email new_name@example.com

http://tobysoft.net/wiki/index.php?git%2F%A5%B3%A5%DF%A5%C3%A5%C8%A5%ED%A5%B0%A4%F2%BD%A4%C0%B5%A4%B9%A4%EB%CA%FD%CB%A1

これで問題なく名前を付けることができた。

GitHub実践入門 ~Pull Requestによる開発の変革 (WEB+DB PRESS plus)

GitHub実践入門 ~Pull Requestによる開発の変革 (WEB+DB PRESS plus)

rubyとcrontabで毎朝、休講情報を取得するプログラムを作成した話

はじめに

私は、学内アルバイトとして、TA(Teaching Assistant)をしている。基本的な業務は、簡単なエクセルの使い方やワードの使い方などを教えている。 しかし、TAは授業を履修していないため、休講情報の通知が来ない。

休講情報はベーシック認証があるサーバに存在しており、自動で取得し通知することを考えた。

ロジック

--- ruby ---

  1. 外部からアクセス可能(basic認証)なウェブサイトの休講情報を取得する
  2. 整形させる
  3. 当日の休講情報を抽出/出力

crontabで、上記のプログラムを毎朝実行し、メールする。 これらを、ウェブサービスを公開するために借りたVPSにおいておく。

http://hagetak.hatenablog.com/entry/2015/02/20/232004

書いてみた。

require 'nokogiri'
require 'mechanize'

agent = Mechanize.new
agent.add_auth('http://www.gakkounowebsite.info/', 'userid', 'password')
@page = agent.get('http://www.gakkounowebsite.info/?page_id=1028')

@content = @page.search('.entry-content')

@class_datas = []

# 検索用 => "6月12日"という文字列を検索するために
b = Time.now
@today = "#{b.month}#{b.day}"

# <p>6月12日 情報倫理<br>\n 教室:1201教室... </p>
# <p>6月12日 財務諸表<br>\n 教室:1203教室... </p>
# => ['6月12日 情報倫理...', '6月12日 財務諸表']
@content.xpath("//p").each do |c|
    @class_datas << c
end

a = []
@sending_datas = []
# [0] => date
# [!0] => className, teacher, remarks
# @class_datas[0] => "6月22日(月)\n 2限:情報演習・基礎 \n 担当:斉藤先生 \n 補講:課題指示あり"
# a[0] => ["6月22日(月)", "2限:情報演習・基礎", "担当:斉藤先生", "補講:課題指示あり"]
@class_datas.each do |info|
    a << info.text.split("\n")
end

# 本日休講の項目を取得
a.each do |s|
    s[0].tr!("0-9", "0-9")
    @sending_datas << s if(s[0].to_s.match(@today))
end

puts '休講情報はありません' unless @sending_datas
@sending_datas.each do |s|
    puts '*** ' * 10
    puts s
end

今こうしてみると、読みづらく、気持ち悪いね。整形作業に手間がかかってる感じ。もう少し簡単にできないだろうか...。

crontabの設定

crontabについて学んだことは、後日記事にする。 さて、このプログラム(fetch_class_info.rb)をcrontabで動かしたいと思う。

いかのプログラムを書いて、動かしている。

35 7 * * * /home/hagetak/.rbenv/shims/ruby  /home/hagetak/cron/fetch_class_info.rb | mail -s `echo $(date +'\%Y/\%m/\%d')休講情報` your_email_address@domain.com

一つ一つ見てみると、わかるだろう。

minites hour * * * [実行するプログラム]

という感じで、この例では、毎日7時35分に実行するプログラムだ。所有者・実行者が違うと、PATHが通っていない可能性があるので、絶対参照でプログラムを実行させることにした。

実行させたい大本のプログラム(ruby だったり, pythonだったり...)は、whichコマンドで確認することができる。

> which ruby 
  => /home/hagetak/.rbenv/shims/ruby

ruby yourprogram.rb

で実行できるので、rubyファイルは絶対参照で記述。

次のステップは、少しややこしい。(件名を日本語/変更したくない場合はこの処理は飛ばして良い)

mail -s echo $(date +'\%Y/\%m/\%d')休講情報 your_email_address@domain.com

実行した結果を mail コマンドに受け渡し、送信するというモノだ。

echo $(date +'\%Y/\%m/\%d')休講情報

これは、いつの休講情報かわからないために追加したもの。

crontabのshに問題があるため、dateコマンド内の%はバックスラッシュでエスケープすること

この処理で引っかかって、1日ずっと考えていた...。

dateコマンド と crontab の コマンドライン中の %(パーセント)記号 - keigoiの日記

さて、これらをまとめると、以下に置き換えられるだろう。

result of your program | mail -s "件名" your_email_address@domain.com

cron処理結果を、subjectを日本語にしてメールする方法 | Web開発者の備忘録

知見

  • いきなり毎朝...で設定すると気が遠くなるので、以下に変更すると良い(毎分)

*/1 * * *

  • メールが届かない!ってときは、次のコマンドを打つと出ている

mail

  • 件名とかいらない。ってときは簡略なものでできる
MAILTO="your_email_address@domain.com"

*/2  *  *  *  * /usr/bin/ruby /Users/hagetak/cron/fetch_class_info.rb

Mac版無償提供の「Visual Studio Code」を早速使ってみた感想

はじめに

朝、起きたらTLが「Visual Studio Code」の一色になっていた。ほほう、あのマイクロソフト株式会社がMacOS向けにエディタを提供したのか。

マイクロソフトは囲い込みが印象強いが、今回の公開で結構印象が変わった。たぶん、TLにいる皆さんもそう思っているのではないか。

気になったので早速ダウンロードして、使ってみた。

ダウンロード

次のサイトからダウンロードできる。該当するOSを選択してください。

https://code.visualstudio.com/Download

GoogleVisual Studio って検索しても多分出てこないと思う。自分もそれで苦戦した。

使ってみた。

前回の記事にあるフィボナッチ数列のプログラムを書いてみた。

感想

コード補完(2/5)

まだまだコード補完が甘いな、というのが印象。補完が全てじゃないけど、補完の強さが一つの指標になると思っている。

まだまだ出始め、プレビュー版であるので今後は様々なプラグインやパッケージが出てくることを祈りましょう。

ものによっては、コード補完が強いらしい。

軽さ(5/5)

これは驚いた。すごく軽い。コード補完プラグインがない分軽いのは当たり前なんだが、すごく軽いよね。(軽さとコード補完の強さはトレードオフ関係にあると思う。)ちょっとしたコードを書くときは、低補完でさくさくと書いていくのが良いんじゃない?

見た目(4/5)

クール。これもカスタマイズできるはず。今後出てくるはず。

操作感(3/5)

ここが結構重要で、今まで一番上・一番下にいくショートカットキーは、Command + ↕だったんだが、これができず、操作がしづらい。

基本、Emacsのコマンドは使えるっぽいので、(Ctrl - a, Ctrl - e)慣れている人はすごく使いやすいと思う。自分はあまりコマンドを知らず、慣れてないので違和感がすごくある。

さいごに

自分が使いこなせていない感がありまくり。

今後、Visual Studio Code がどう発展していくかにより、メインエディタが決まってくる。

本来、こうやって任せっきりにするのが素人なんだよね。なら、自分で使いやすくしよう!ってのがプロだよね...。

なんか貢献できることがあれば貢献していきたいな。

Emacs実践入門 ?思考を直感的にコード化し、開発を加速する (WEB+DB PRESS plus)

Emacs実践入門 ?思考を直感的にコード化し、開発を加速する (WEB+DB PRESS plus)