Home

sinsengumi血風録

JavaでMapコレクションの繰り返し

  • Posted by: sinsengumi
  • 2010年10月22日 11:34 AM
  • Java

毎回忘れて、調べてるのでメモ。

public class Sample {

    public static void main(String[] args) {

        Map<Integer, String> map = new HashMap<Integer, String>();
        map.put(0, "Kondou");
        map.put(1, "Hijikata");

        for (Entry<Integer, String> e : map.entrySet()) {
            System.out.print(e.getKey());
            System.out.print(" ");
            System.out.println(e.getValue());
        }
    }
}

JavaのHttpClient 4 を触ってみた。

  • Posted by: sinsengumi
  • 2010年10月7日 11:30 AM
  • Java
  • |

HttpClientの3.0系はレガシーということで、4系を触ってみました。
実行環境は以下です。

  • JRE 1.6
  • HttpClient 4.0.3 (httpclient-4.0.3.jar)
  • HttpCore 4.0.1 (httpcore-4.0.1.jar)
  • Commons Logging 1.1.1 (commons-logging-1.1.1.jar)

簡単に、HTTP接続ができていい感じです。

サンプルは以下。

public class HTTPSample {

    private static HttpClient httpClient = new DefaultHttpClient();

    public static void main(String[] args) {

        // プロキシがある場合は、以下のようにして設定する
        //HttpHost proxy = new HttpHost("XXX.XXX.XXX.XXX", 8080);
        //httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);

        Map<String, String> requestParams = new HashMap<String, String>();
        requestParams.put("pattern", "ltrim");
        requestParams.put("lang", "ja");

        httpGet("http://jp2.php.net/manual-lookup.php", requestParams);
        // httpPost("http://jp2.php.net/manual-lookup.php", requestParams);

        // HTTP接続を閉じる(shutdownを実行するとセッションが切れます)
        httpClient.getConnectionManager().shutdown();
    }

    private static void httpGet(String url, Map<String, String> requestParams) {

        HttpGet httpGet = null;

        try {
            // リクエストパラメータの設定
            StringBuilder builder = new StringBuilder(url);
            builder.append("?");
            for (Map.Entry<String, String> entry : requestParams.entrySet()) {
                builder.append((String) entry.getKey());
                builder.append("=");
                builder.append((String) entry.getValue());
                builder.append("&");
            }

            String tmpUrl = builder.toString();
            tmpUrl = tmpUrl.substring(0, tmpUrl.length() - 1);

            httpGet = new HttpGet(tmpUrl);

            System.out.println("executing request " + httpGet.getURI());
            System.out.println("-------------------------------------");

            HttpResponse response = httpClient.execute(httpGet);

            // レスポンスヘッダーの取得
            System.out.println(response.getStatusLine().getStatusCode());

            Header[] headers = response.getAllHeaders();
            for (Header header : headers) {
                System.out.println(header.getName() + ": " + header.getValue());
            }

            System.out.print(System.getProperty("line.separator"));

            // レスポンスボディの取得
            HttpEntity httpEntity = response.getEntity();
            System.out.println(EntityUtils.toString(httpEntity));

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (httpGet != null) {
                httpGet.abort();
            }
        }
    }

    private static void httpPost(String url, Map<String, String> requestParams) {

        HttpPost httpPost = null;

        try {
            // リクエストパラメータの設定
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            for (Map.Entry<String, String> entry : requestParams.entrySet()) {
                params.add(new BasicNameValuePair((String) entry.getKey(), (String) entry.getValue()));
            }

            httpPost = new HttpPost(url);
            httpPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));

            System.out.println("executing request " + httpPost.getURI());
            System.out.println("-------------------------------------");

            // レスポンスヘッダーの取得
            HttpResponse response = httpClient.execute(httpPost);
            System.out.println(response.getStatusLine().getStatusCode());

            Header[] headers = response.getAllHeaders();
            for (Header header : headers) {
                System.out.println(header.getName() + ": " + header.getValue());
            }

            System.out.print(System.getProperty("line.separator"));

            // レスポンスボディの取得
            HttpEntity httpEntity = response.getEntity();
            System.out.println(EntityUtils.toString(httpEntity));

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (httpPost != null) {
                httpPost.abort();
            }
        }
    }
}

参考

Smartyのテンプレート側でPHPの標準関数を使用する

  • Posted by: sinsengumi
  • 2010年10月1日 10:42 AM
  • PHP
  • |

Smartyのテンプレート側ではPHPの標準関数を使用することができます。
使い方は、変数の修飾子として関数を使用します。

変数の修飾子は、 変数 や カスタム関数 や文字列を修飾して出力することができます。修飾子を適用するには、 変数名の後に | (パイプ) と修飾子の名前を指定します。 また、修飾子はその動作に影響を及ぼす追加のパラメータを受け入れる場合もあります。 そのパラメータは修飾子の後に続き、: (コロン) によって区切られます。 また、すべての PHP 関数は、暗黙的に修飾子として使用でき (あとで説明します)、修飾子は 組み合わせる こともできます。
Smarty マニュアル | 第5章変数の修飾子

使用する際の注意点としては以下があります。

  • 関数に適用する変数が配列の場合、関数名の前に「@」をつける。
  • 「|(パイプ)」の後に書いた関数の第一引数に変数が渡される。関数の引数が2つ、3つあるような関数の場合は変数を「:(コロン)」で区切って記述します。

配列に対して修飾子を用いた場合は、その配列に格納された全ての値に影響を及ぼします。 配列全体を1つの値として作用させるには修飾子の先頭に @ 記号をつける必要があります。
Smarty マニュアル | 第5章変数の修飾子

使用例は以下です。

<!-- 変数(string)を大文字にする -->
<p>{$title|upper}</p>

<!-- 配列の要素数を取得する -->
<p>{$array|@count}</p>

<!-- パラメータが2つ以上ある場合($language = "PHP関数") -->
<p>{"PHP"|str_replace:"Ruby":$language}</p>

参考

XAMPP 1.7.3にPHPUnit 3.5をインストールする

XAMPP(Lite)環境にPHPUnitをインストールした時にかなりはまったので、そのメモです。
環境は以下。

  • XAMPP Lite 1.7.3 for Windows(PEARははじめからインストールされています)
  • PHPUnitのバージョンは3.5

PEARを最新版にアップグレードする

まずcmdでxamppのphpディレクトリに移動して(pearコマンドのパスが通っている場所)、PEARのバージョンを確認します。
恐らく以下のように、1.9.0のはずなので、最新版にアップグレードします。(アップグレードしないと、PHPUnit3.5のインストールが中途半端になります

cd C:\xampplite\php
pear version
>PEAR Version: 1.9.0
>PHP Version: 5.3.1
>Zend Engine Version: 2.3.0
>Running on: Windows NT XX 5.1 build 2600 (Windows XP Professional Service Pack 3) i586

以下のコマンドでPEARをアップグレードします。これで1.9.1になると思います。

pear upgrade PEAR
pear version

PEARチャネルを追加する

以下のコマンドを打ち、PEARチャネルを追加します。

pear channel-discover pear.phpunit.de
pear channel-discover components.ez.no
pear channel-discover pear.symfony-project.com

PHPUnitをインストールする

以下のコマンドでインストールします。

pear install phpunit/PHPUnit

以下のコマンドで追加したチャネルにPHPUnitで必要なライブラリがインストールされていることを確認します。

pear list -a

PHPUnitを実行する

以上の手順を踏むと、C:\xampplite\phpに「phpunit.bat」ができていると思います。
そのバッチファイルを実行し、正しく動いているか確認します。

phpunit --version
>PHPUnit 3.5.0 by Sebastian Bergmann.

参考

MacでWebサイトを一括ダウンロードするフリーソフト

Webサイトをリニューアルするときなど、既存のサイトを丸ごと落としてローカル環境に構築したい場合があるんですが、FTPがあればいいですが、それがない場合は、サイトのリンクを辿って一括ダウンロードということをよくします。

WindowsではWebsite Explorerという素晴らしいソフトがあるんですが、Macで同じようなのないかなぁと思ったらありました。

SiteSucker
http://www.sitesucker.us/mac.html

SiteSucker(スクリーンショット)

Website Explorerほど高機能ではないですが、一括ダウンロードは十分できます。

php.iniでsession.save_pathを設定しない(no value)とどうなるか?

とある環境でphpinfo()をしてみたらsession.save_pathの欄が「no value」となっていて、
「あれ?これじゃあセッション使えないんじゃない?」と思って調べてみました。

検証環境は以下。

  • php4.4.1(とある業務の都合でめちゃ古いです。。でもphp5でも同じかと)
  • IIS6.0

php.ini

session.save_path =
session.cookie_path =

結果

session.save_pathは指定しない(no value)と、IIS(Windows)の場合「C:\WINDOWS\Temp」に「sess_XXX」という名前で勝手に保存します。
またsession.cookie_pathは指定しないと、「/」(ルート)に勝手に設定されます。
なので、これらが設定されていないからといって、セッションが使えないということはなさそうです。

JQueryでAjaxしてみる

HTMLを書く

まずHTMLを用意します。JQueryを読み込みます。Ajax通信を書くJavaScriptは別ファイルにしています。
さらに、受け取ったサーバーから受け取ったJSON形式をパースするためにjson2を使用します。
json2はこちらからダウンロード。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="content-style-type" content="text/css" />
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="json2.js"></script>
<script type="text/javascript" src="insert.js"></script>
<title>AjaxTest</title>
</head>
<body>

<input type="text" name="todo" id="todo" size="30" value="" />
<input name="insert-btn" type="button" value="追加" onclick="javascript:insertAjax();" />
<div id="error-message" style="color: red;"></div>
<div id="response-message" style="color: blue;"></div>

</body>
</html>

JQueryでAjax通信を書く

今回はサーバーから受け取るデータをJSON形式にしています。JavaScriptではJSON形式にしておいたほうが処理がしやすいです。

POSTで送るパラメータはdata:に記述していきます。
また正常時と異常時の場合に起動する関数をsuccess:, error:に書いていきます。
今回は関数オブジェクトとして別に定義していますが、ここにそのまま書く事もできます。

insert.js

function insertAjax() {
    $.ajax({
        type: "POST",
        url: "./insert.php",
        dataType: 'json',
        data: "todo=" + $('#todo').val(),
        success: handleSuccess,
        error: handleError
    });
}

var handleSuccess = function(data, dataType) {
    // HTMLを追加する
    // JSON形式のdataは、配列ならdata[0]、オブジェクトならdata.todoなどとして扱える
    $("#response-message").append(data + "がDBに挿入されました。");
}

var handleError = function(XMLHttpRequest, textStatus, errorThrown) {
    // HTMLを追加する
    $("#error-message").append(JSON.parse(XMLHttpRequest.responseText));
}

サーバー側(PHP)の処理を書く

ポイントはサーバー側で出力したものが、そのまま$.ajaxのsuccess:で指定する関数オブジェクトの第一引数(ここではdata)に入ってくるということです。
出力する文字列は必ずjson_encode関数でJSONエンコードしてから出力すること。

ちなみに今回は入力チェックでNGだった場合に、header関数で403を返しています。
なぜそのようなことをするかというと403で返すことにより、$.ajaxでerror:が呼ばれて、エラー処理ができるからです。
ただこのようなやり方が正しいやり方なのかはわかりません。入力チェックで403を返すのも変な感じがしますし。

insert.php

<?php
// 送られてきたデータを取得
$todo = isset($_POST['todo']) ? $_POST['todo'] : NULL;

// 入力チェック
if (is_null($todo) || $todo === "") {
    // JQueryのAjaxでerrorとさせるため403を返却する。
    header('HTTP/1.0 403 Forbidden');
    $result = "NG";
    echo(json_encode($result));
} else {
    // DBにデータを挿入する。
    // ~省略~
    $result = $todo;
    echo(json_encode($result));
}
?>

実行結果

JQueryでAjaxしてみるの実行結果

参考

JQueryで要素の存在チェック

要素が存在しているかのチェックはlengthメソッドを使用して行います。

function checkExist() {
    if ($('#contents').length) {
      alert('存在します。');
    }
}

SmartyでURLを自動リンクするプラグイン

  • Posted by: sinsengumi
  • 2010年9月6日 4:25 PM
  • PHP
  • |

プラグインを配置する

Smart/libs/pluginsにmodifier.auto_link.phpという名前でPHPファイルを配置する。

関数を書く

modifier.auto_link.phpに以下を記述する。

<?php
/**
 * URL自動リンクプラグイン<br>
 * 指定された文字列にURLが含まれる場合、その個所をaタグで囲む。<br>
 *
 * @param string 文字列
 * @return string URLをaタグで囲んだ文字列
 * @access public
 */
function smarty_modifier_auto_link($string) {
    // nullまたは空文字の場合、そのまま返却する。
    if (is_null($string)) {
        return $string;
    }

    // URL形式のチェック用正規表現
    $regString = '/(https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)/';

    return preg_replace($regString, "<a href=\"\\0\" target=\"_blank\">\\0</a>", $string);
}
?>

使い方

<p>{$var|auto_link}</p>

参考

aタグで#を設定した際URLに#を付けなくする方法

aタグにonclickとか設定して、リンクさせたくない場合、<a href=”#”>とかしますが、それだとそこをクリックした際に、URLの末尾に「#」がついて気持ち悪いので、それをさせない方法です。

以下のように記述します。

<a onclick="function_name(); return false;" href="javascript:void(0);">test</a>

javascript:void(0);でリンクを無効にし、return falseでクロスブラウザで挙動を合わせる場合に、onclickしても、見せ掛け上処理が無効となるようにしている。

参考

Home

Search
Feeds
Meta

Return to page top