Kinopyo Blog

プログラマとしてRuby, Rails, iPhone, iPad,Macなどなどと向き合う日々のログポース

Posts Tagged ‘Snippet’

PHP プロセス数を指定して実行するマルチスレッド処理(curl_multi)

2011年08月09日

curl_multi系を使って、プロセス数を指定して実行するマルチスレッド処理です。

urlは配列で受け取って、もし指定したプロセス数より多い場合は分割して実行するようになってます。

このサンプルコードではこのブログの幾つかのurlに対してtitleを取得しました。

<?php
/**
* 指定したプロセス数で並列処理を実行する
*
* @param array $url_list URLの配列
* @param boolean $url_as_key 結果配列を返すときに、urlをキーにする
* @param int $timeout タイムアウト秒数 0だと無制限
* @return array 結果配列
*/
function execute($url_list, $url_as_key = false, $timeout=0) {
    // set your process number
    $process = 5;

    $is_over_process = false;
    if ($process < count($url_list)) {
        // chunk url list / process number*
        $url_chunk = array_chunk($url_list, $process);
        $is_over_process = true;
    }

    $ret = array();
        
    if ($is_over_process && !empty($url_chunk)) {

        foreach ($url_chunk as $key => $url_list) {
            echo "chunk start:{$key}\n";
            
            $res = fetch_multi_url($url_list, $url_as_key, $timeout);
            if (!empty($res)) {
                $ret = array_merge($ret, $res);
            } else {
                continue;
            }

        }
    } else if (!$is_over_process && !empty($url_list)){
        $ret = fetch_multi_url($url_list, $url_as_key, $timeout);
    } else {
        echo "url invalid::";
    }
    
    return $ret;
    
}

/**
* curl_multi_execの並列処理
* ほぼboilerplate
*
* @param array $url_list URLの配列
* @param boolean $url_as_key 結果配列を返すときに、urlをキーにする
* @param int $timeout タイムアウト秒数 0だと無制限
* @return array 結果配列
*/
function fetch_multi_url($url_list, $url_as_key, $timeout) {
    $mh = curl_multi_init();
    foreach ($url_list as $i => $url) {
        $ch[$i] = curl_init($url);
        curl_setopt($ch[$i],CURLOPT_RETURNTRANSFER,1);

        //タイムアウト
        if ($timeout){
            curl_setopt($ch[$i],CURLOPT_TIMEOUT,$timeout);
        }

        curl_multi_add_handle($mh,$ch[$i]);
    }

    //URLを取得
    //すべて取得するまでループ
    $active = null;
    do {
        $mrc = curl_multi_exec($mh,$active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);

    while ($active and $mrc == CURLM_OK) {
        if (curl_multi_select($mh) != -1) {
            do {
                $mrc = curl_multi_exec($mh,$active);
            } while ($mrc == CURLM_CALL_MULTI_PERFORM);
        }
    }

    if ($mrc != CURLM_OK) {
        echo '読み込みエラーが発生しました:'.$mrc;
    }

    //ソースコードを取得
    $res = array();
    foreach ($url_list as $i => $url) {
        if (($err = curl_error($ch[$i])) == '') {
            // url_as_keyがtrueの場合、urlをキーとして格納
            if ($url_as_key) {
                $res[$url] = curl_multi_getcontent($ch[$i]);
            // そうでない場合は、ただ配列に入れる
            } else {
                $res[$i] = curl_multi_getcontent($ch[$i]);
            }
        } else {
            echo '取得に失敗しました:'.$url_list[$i].'<br />';
        }
        curl_multi_remove_handle($mh,$ch[$i]);
        curl_close($ch[$i]);
    }
    curl_multi_close($mh);

    return $res;
}


// 並列実行したいurl list
$url_list = array(
    "http://www.kinopyo.com/blog/ipad-2-not-charging-when-connected-to-pc-usb",
    "http://www.kinopyo.com/blog/the-first-app-i-installed-to-ipad2",
    "http://www.kinopyo.com/blog/chrome-warn-before-quitting-with-command-q-in-mac",
    "http://www.kinopyo.com/blog/reply-to-all-always-in-gmail",
    "http://www.kinopyo.com/blog/lion-fullscreen-shortcut-key-conflict-with-evernote-client",
    "http://www.kinopyo.com/blog/how-to-set-gesture-for-chrome-to-swipe-back-and-forth-in-lion",
    "http://www.kinopyo.com/blog/3-free-ebooks-for-study-coffeescript"
);

// start time
$start_time = microtime(true);

// execute
$res = execute($url_list, true);

// execute time
$time = microtime(true) - $start_time;

// play with the result
// here I just get the page title
$titles = array();
foreach ($res as $url => $html) {
    preg_match('{<title>(.*)</title>}',$html, $match_title);
    $titles[$url] = $match_title[1];
}

echo "Result:\n";
echo "time:{$time} sec\n";
print_r($titles);

参考:PHPでマルチスレッド(バックグラウンド処理)を実現する方法

githubの/usrが削除されたスレットが面白かった、Nokogiriで画像を拾うSinatra appを書いた

2011年06月21日

スレット経緯

bumblebeeというgithubのプロジェクトにinstall.shというファイルがありますが、

実行するとrm -rf /usrのコマンドで/usrが全部削除されることで大騒ぎになったようです。

githubのスレット

一個スペースが多かったですね。。

でコメントに上がっている画像がとても面白かったので、それをNokogiriを使って拾うrubyコードを書きました。プログラマのヒューモア満載の画像ですね。

Sinatra + Nokogiri + Herokuで作りました、キャッシュはdalliというgemを使いました。

成果

下記iframeで表示しています。urlはhttp://kinopyo-omgmyusr.heroku.com

ソースコード

githubに上げています。

https://github.com/kinopyo/Funny-Images-in-bumblebee-rm–rf–usr-thread

参考になったリンク:

http://devcenter.heroku.com/articles/memcache

PHPで他のJSON形式APIをコールするサンプルコード

2011年03月07日

file_get_contentsとjson_decodeの組み合わせでAPIコールするサンプルコードです。

// APIコール
$api_url = 'http://example.com/api/';
$api_ret = file_get_contents($api_url);

// JSONにデコード
$api_result = json_decode($api_ret,true);

// APIエラーチェック: 何かしらの成功フラグでチェック
if(isset($api_result['success']) && $api_result['success'] == 0)
{
    // 処理
}
else
{
    // handle error
}

Spring DataSource beanのメモ

2010年12月06日

DataSource Beanを定義する際applicationContext.xmlの書き方と、Javaで呼び出すコードのメモです。ずいぶん昔のメモです。。

こんなjdbc.propertiesファイルがクラスパスにあるとします。

jdbc.driverClassName=org.h2.Driver
jdbc.url=jdbc:h2:~/test
jdbc.username=sa
jdbc.password=

そしてSpringのapplicationContext.xmlにはこう書きます。

<context:property-placeholder location="jdbc.properties"/>

<bean id="dataSource"
	class="org.springframework.jdbc.datasource.DriverManagerDataSource">
	<property name="driverClassName" value="${jdbc.driverClassName}" />
	<property name="url" value="${jdbc.url}" />
	<property name="username" value="${jdbc.username}" />
	<property name="password" value="${jdbc.password}" />
</bean>

<bean id="accountDao" class="test.dao.AccountDao">
	<property name="dataSource" ref="dataSource" />
</bean>

Javaでの呼び出し:

ApplicationContext context = new ClassPathXmlApplicationContext(
		"applicationContext.xml");

AccountDao accountDao = (AccountDao) context.getBean("accountDao");

// other code...

JavaScript: カンマ区切りで数値をフォーマットする

2010年11月29日

/**
 * 数値を日本円表現にフォーマット。
 * 例:12345 -> 123,45
 *
 */
num2Currency = function(obj){

	// 画面項目の値
	var str=obj.value;
	var num = new String(str).replace(/,/g/"");
	while(num != (num =num.replace(/^(-?\d+)(\d{3})/,"$1,$2")));
	obj.value = num;

}

/**
 * 日本円表現を数値にフォーマット。
 * 例:123,45 -> 12345
 *
 */
currency2Num = function(obj){

	var str=obj.value;
	var num = str.replace(/,/g,"");
	obj.value = num;
}

Flexでシステムクリップボードに内容をコピーするには

2010年05月06日

テキストをクリップボードにコピーするコードです。

System.setClipboardの第一引数にテキストを渡せばOKです。

System.setClipboard(text);

ここにいいDEMOがあります。

jspにメソッドを定義するには

<&!~&>宣言部でメソッドを定義することができます。

<%!
private String myMethod (String str) {
    // some code
    return "ok";
}
%>

参考サイトはこちら:

J2EE講座 [ JSPの基本構文 ]

jQuery siblings()とchildren()の内部ソースを見た

2010年04月19日

よく出来ていると思います。

勉強になります。

siblings: function( elem ) {
	return jQuery.sibling( elem.parentNode.firstChild, elem );
},
children: function( elem ) {
	return jQuery.sibling( elem.firstChild );
},

そしてjQuery.sibling()の中身です!

nodeTypeが1の場合はelementノードの意味です。

nはループに使われて、elemは除外する要素です。

例えばsiblings()の場合は自分自身を除外しています。

for文の書き方も覚えとこう、、

javaでのIteratorのhasNext()関数みたいな動きをしていますね。


	sibling: function( n, elem ) {
		var r = [];

		for ( ; n; n = n.nextSibling ) {
			if ( n.nodeType === 1 && n !== elem ) {
				r.push( n );
			}
		}

		return r;
	}

スクロールを最下部に移動するJavascript

2010年03月02日

スクロールバーを最下部に移動するJavascriptです。

普通のJavascriptで書くと

function go_bottom(targetId){

    var obj = document.getElementById(targetId);

    if(!obj) return;

    obj.scrollTop = obj.scrollHeight;
}

完全にjQueryで書くとこんな感じ

function go_bottom(targetId){

   var $obj = $("#" + targetId);

    if($obj.length == 0) return;

    $obj.scrollTop($obj[0].scrollHeight);
}

これ以外はhiddenのinput項目を最下部に置いといて、

それをfocusするような技もありけど、、

jQuery $.inArray()関数の戻り値に注意を

2010年01月15日

$.inArray(value, array)

指定した値が配列中にあれば、そのインデックスを返します。

配列に存在しなければ戻り値は”-1″になりますので注意してください。


var array = ["a", "b", "c"];

if ($.inArray("d", array) == -1) {

    // d is not in array

}

下記のコードは間違いですよ。。。

if ($.inArray("d", array)) {}

$.isArray(obj)

パラメータで渡された値が配列であるかどうかを判別します。

戻り値はtrueかfalseです。