2012 年 2 月
« 7 月    
 12345
6789101112
13141516171819
20212223242526
272829  

最近のコメント

    EC-CUBE2.4.3のバグ!?

    EC-CUBE2.4.3をMySQL4.1で利用すると、管理画面の受注履歴編集画面の商品の追加で、システムエラーとなります。

    ログイン→受注管理→受注履歴検索→受注履歴編集画面→商品追加ボタンクリック→商品検索画面(ポップアップ)

    →カテゴリを選択、または商品名を入力→検索を開始ボタンクリック→システムエラー!!

    原因を調査したところ、ファイル「/data/class/pages/admin/order/LC_Page_Admin_Order_ProductSelect.php」の

    商品検索SQLを発行した瞬間に「#1052 - Column ‘product_id’ in IN/ALL/ANY subquery is ambiguous」という

    MySQLのエラーが発生していました。

    このエラーは、カラム「‘product_id’」があいまいな指定になっているという事を指摘しており、

    SQLの対象テーブルのうち、SELECT句の中に2つ以上のテーブルに存在するカラム「‘product_id’」を指定している場合によく起こります。

    (例)TABLE_AとTABLE_BにあるIDを取得する。

    SELECT A.ID, B.ID FROM TABLE_A AS A, TABLE_B AS B  

    と記述すべきところを

    SELECT ID, ID FROM TABLE_A AS A, TABLE_B AS B

    と記述してしまった場合、SELECT句にある「ID」「ID」はTABLE_AとTABLE_BのどちらのIDなのか

    コンピュータは判断する事ができません。
    (人間でも、ルールを知らなければ、判断できません。)

    そこでMySQLは、カラム「ID」があいまいな指定になっているとエラーを出力します。

     

    ここで発行しているSQLが、「/data/logs/site.log」に記録されていましたので、確認したところ、

    上記「LC_Page_Admin_Order_ProductSelect.php」の100行目と105行目付近の商品検索条件をセットしているところで、

    $where.= ” AND product_id IN (~

    と、SQLを記述しており、どのテーブルのカラム「product_id」か指定されていません。

    よって、上記の箇所を、

    $where.= ” AND T1.product_id IN (~ 

    というように修正して、テーブルをきちんと指定する事でエラーは回避できます。

    が、残念な事に、該当の箇所は、商品マスタ検索機能でも流用されている為、

    今度は、商品マスタ検索機能でエラーが発生するようになります。

    (商品マスタ検索機能は、dtb_productしか検索の対象としていない為、T1を指定するとテーブルが見つからないというエラーが発生!)

    よって、以下のように商品検索と商品マスタ検索の処理を別々に分けて修正する必要があります。

    (97行目付近のCASE文)

    case ’search_category_id’:
         list($tmp_where, $tmp_arrval) = $objDb->sfGetCatWhere($val);
         if($tmp_where != “”) {
             $whereSelect = $where . ” AND T1.product_id IN (SELECT product_id FROM dtb_product_categories WHERE ” . $tmp_where . “)”;
             $where.= ” AND product_id IN (SELECT product_id FROM dtb_product_categories WHERE ” . $tmp_where . “)”;
             $arrval = array_merge((array)$arrval, (array)$tmp_arrval);
         }
    break;
    case ’search_product_code’:
        $whereSelect = $where . ” AND T1.product_id IN (SELECT product_id FROM dtb_products_class WHERE product_code LIKE ? GROUP BY product_id)”;
        $where .= ” AND product_id IN (SELECT product_id FROM dtb_products_class WHERE product_code LIKE ? GROUP BY product_id)”;
        $arrval[] = “$val%”;
    break;
    default:

     

    さらに170行目付近のSQLを実行するselectメソッドの引数を$whereSelectに変更します。

    // 検索結果の取得
    $this->arrProducts = $objQuery->select($col, $from, $whereSelect, $arrval);

    これで、問題なく商品検索が動作すると思います。

    ちなみにMySQL5の場合、このエラーは発生せずに処理が実行されます。

    EC-CUBE2.4をさくらレンタルサーバ(共有サーバ)で運用する!!

    さくらレンタルサーバのスタンダードコースでは、

    .htaccessでのPHPの設定変更が行えない為、EC-CUBEをそのままインストールしただけでは、

    正常に動作しない可能性があります。

    (.htaccessにphp_valueやphp_flagの記述が存在すると、500-internal server errorが発生!!)

     

    私が確認している現象は、商品登録時に以下のエラーメッセージが表示されます。

    Warning: in_array() [function.in-array]: Wrong datatype for second argument in <エラーが起こっているファイルと行数>

    (またはエラーは表示されず、商品カテゴリが登録できない現象が発生します。)

     

    原因は、PHPの設定で「magic_quotes_gpc 」ディレクティブがONになっている為に起こる自動エスケープ処理のようです。

    エラーの箇所を調査して、処理を遡ったところ、

    /data/class/pages/admin/products/LC_Page_Admin_Products_Product.phpの450行目付近に、

    $arrList['category_id'] = unserialize($arrList['category_id']);

    という1文があり、この直後から$arrList['category_id']の中身が空となっておりました。

     

    商品確認画面より受け取った「$arrList['category_id']」の中身を確認してみると、以下の通り、余計なバックスラッシュが含まれています。

    a:2:{i:0;s:1:\”2\”;i:1;s:1:\”1\”;}

    正常に動作しているEC-CUBEの同じ箇所での「$arrList['category_id']」の中身は以下の通りです。

    a:2:{i:0;s:1:”2″;i:1;s:1:”1″;}

    magic_quotes_gpc 」ディレクティブがONの為、

    商品確認画面より受け取るPOST変数に対して、エスケープ処理を自動的に行い、

    データ中の「”」が「\”」に変換されてしまい、unserialize関数で予期せぬ事態が起こっているようです。

     

    対策として、さくらレンタルサーバは、サーバ管理画面よりPHP.iniを設定できるようになっていますので、

    EC-CUBEに付属している.htaccessの内容を以下のとおり、書き換えてPHP.iniを設定し、

    さらに.htaccessを削除する事で、正常に動作させる事ができます。

    mbstring.language = Japanese
    output_handler = mb_output_handler
    mbstring.encoding_translation = 1
    magic_quotes_gpc = 0
    mbstring.internal_encoding = UTF-8
    upload_max_filesize = 5M

    また、携帯電話用フォルダにも.htaccessがあるので、忘れずに削除してください。

    phpPgAdminで自動ログイン!?

    突然ですが、PostgreSQLを久々に触ってみました。

    PostgreSQL8.4をWindowsXP Pro + Apache2.2 + PHP5.2.13の環境にインストールして、

    phpPgAdmin4.2.3をセットアップ。

    とりあえず、config.inc.phpをコピー&編集して、phpPgAdminをブラウザに表示させました。

     

    ここで1つ疑問が・・・。

    phpMyAdminには、USERアカウントとPASSWORDをconfigファイルに記憶させておいて、

    自動ログインさせる事ができますが、phpPgAdminで同じような事ができるのでしょうか?

    早速、ソースを調べてみたところ、ログインの時に以下のファイルの情報を読み込んで利用しているようです。

    /phpPgAdmin4.2.3/libraries/adodb/adodb.inc.php

    上記のファイルの244行~246行目を以下のように変更して、phpPgAdminを再表示します。

    var $host = ‘postgreSQLが稼動しているサーバ名’;    /// The hostname of the database server 
    var $user = ‘postgreSQLにログインするアカウント’;    /// The username which is used to connect to the database server.
    var $password = ‘PostgreSQLにログインするパスワード’;   /// Password for the username. For security, we no longer store it.

     

    phpPgAdminのTopページのサイドメニューから、接続したいサーバを選択します。

    選択したサーバへのログイン画面が表示されますので、

    ユーザー名、パスワードを空欄のまま、ログインボタンをクリックします。

    すると、サーバにログインした画面が表示されますので、そのまま操作を続行する事ができます。

    Eclipse3.5が起動しない!!

    ここ最近、CentOSを利用する機会に恵まれて、CentOSを色々といじり倒しております。

    CentOS上で、Java(Struts)を利用したWEBアプリケーションを動作させる必要があり、

    直接ソースの修正が行えたほうが便利ということで、CentOS環境にEclipse3.5をインストールしてみました。

     

    インストール自体は、本家WEBサイトからダウンロードしてきたtar.gzファイルを任意の場所へ展開しただけで簡単に終了しました。

    Eclipseの日本語化についても、Pleiadesプラグインをダウンロード・展開し、plugins、featuresディレクトリの中身を

    Eclipseのplugins、featuresディレクトリにコピーして、

    Eclipse.iniに、「-javaagent:plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar」の一文を加えて、

    再起動しただけで無事終了しました。

     

    そこまではよかったのですが、

    WEBアプリケーションをJava1.4で動作させる為、

    Java1.4をインストールしたのですが、

    その後、Eclipseの起動を実行すると、「セグメンテーション違反です」とエラーメッセージが表示され、

    Eclipseが起動しなくなってしまいました!!

     

    JavaVMのバージョンが怪しいという事で、

    EclipseのJavaVMを指定できるオプションを指定して、起動を実行してみました。

    /usr/local/eclipse -vm /usr/java/jdk1.6.0/jre/bin/java

    ・・・すると、無事、起動!!

     

    やっぱり、JavaVMのバージョンが原因のようでした。

    ただ、Eclipseの起動の度、-vmオプションを設定するのは面倒くさいのです。

    Eclipseには、Eclipseをインストールしたディレクトリ直下にJreディレクトリがあると、

    デフォルトでそのJavaVMを利用する機能があるようですので、

    Eclipseを実行させたいバージョンのJavaのJreフォルダをコピーして、

    WEBアプリケーションと異なるJavaVMで動作するように設定しました。

    (PHP)Smartyのテンプレート利用のエラー

    こんにちは、Eguchiです。

    今日は、開発をしていて少し気になることがありましたので、メモに残しておきます。

    まず開発はEclipse3.5でphpのプログラムを作成する際のケース

    Smartyのテンプレート利用時にとソース最上部で
    記述した際、「syntax error, unexpected ‘version’」というエラーがEclipseの
    コンソールに表示されました。

    どうやら、これは、「」もphpのスクリプトとして、反応するため起きるらしく。
    このままでの記述では、動作自体は問題ないものの、エラーが出て気持ちが悪いです。

    http://kumao.net/pc/2010/02/phpxml-version10-encodingutf-8.html

    上記サイトを参考に考えてみると、
    「<? echo ‘<?<B style=”BACKGROUND-COLOR: #ffff66; COLOR: black”>xml</B> version=”1.0″ encoding=”utf-8″?>’ . “\n”; ?>」
    このような記述でよいのかな?と思います。(まだ未検証)

    ただ、スタイルの設定は必要なのかどうかは疑問なので、

    「<? echo ‘<?xml version=”1.0″ encoding=”utf-8″?>’ . “\n”; ?>」
    このような記述でいいのではないかと思います。(これもまだ未検証)

    ここで、わざわざ最後に「. “\n”」は必要なのだろうかと再び疑問・・・

    「<? echo ‘<?xml version=”1.0″ encoding=”utf-8″?>’ ; ?>」
    これでよいのではないだろうか?(これも未検証)

    なかなか、細かいところですが、泣かれますね。また分かれば追記致します。

    Eclipse3.5でSVNとの接続エラー!!(Subversiveプラグイン)

    Eclipse3.5にSubversiveプラグインをインストールして、

    SVNとの接続を実行しようとした時、突然、以下のエラーが表示されて、リポジトリに接続できなくなりました。

     

    「Unable to open an ra_local session to URL
     Unsupported FS format
     svn: Expected FS format ‘2′; found format ‘4′」

    色々調べてみたところ、

    リポジトリを作成したSVNのバージョンと、クライアントの接続できるバージョンが異なる為、発生するエラーでした。

     

    Eclipseのメニューバー「ヘルプ」→「更新ソフトウェアのインストール」ダイアログを表示して、

    インストールしたプラグインを調べたところ、Subversive SVN コネクターのSVNKit 1.1.7実装(オプション)が原因のようです。
    (どうやらバージョン1.4.xに対応したものらしい・・・)

    subversiveプラグイン追加インストール前
    (Suvversiveプラグインインストール時の画面)

     

    Subversive SVN コネクターのSVNKit 1.3.0実装(オプション)を追加インストールして、

    再度、目的のリポジトリに接続を試みたところ、無事、接続する事ができました。

    subversive2
    (追加インストールした時の画面)

    詳細をよく見ると、バージョンの事が書いてあるようですね。

     

    今回の環境:
    Eclipse galileo php All in One
    日本語化プラグイン pleiades_1.3.1

    Smarty - truncate 利用の注意-

    こんにちは、Eguchiです。

    本日は、PHPの開発時のSmartyののtruncate修飾子についてメモを残して
    おこうと思います。

    truncate修飾子は、指定した文字数で文字列を区切り、末尾に「…」をつけると
    いったものです。
    (例)ああああああああああああああああああ

       あああああ…

    といったような形になります。長い文章を省略表示したいときなどにすごく便利です。

    しかし、シングルバイトなどの文字コードでなら、このtruncate修飾子は
    正常に効いてくれるのですが、
    マルチバイトには対応していないようです。
    truncate修飾子で変換後の「…」の部分が文字化けをおこしてしまうそうです。

    そこで、Smartyを設置しているフォルダのpluginsフォルダにマルチバイトのtruncateを
    作って設置してみると、うまく処理してれるようです。

    実際にその関数を作っている方がいるようです。

    http://webtech-walker.com/archive/2007/04/26154112.html

    上記サイトに詳細と関数のサンプルが記載されています。
    これを「modifier.mb_truncate.php」というファイル名で保存して、設置、
    これまで「truncate」と記述していた部分を「mb_runcate」と記述すれば、
    マルチバイトにも対応することができるようです。

    < 上記URLサイトのサンプルより引用>
    function smarty_modifier_mb_truncate($string, $length = 80, $etc = ‘…’)
    {
    if ($length == 0)
    return ”;
    if (mb_strlen($string,”UTF-8″) > $length) {
    $string = mb_substr($string, 0, $length,”UTF-8″);
    return $string.$etc;
    } else {
    return $string;
    }
    }

    SQLでNULLとNULLは「=」ではありません。

    SQLで2つのテーブルを結合する際、よく利用するテーブルA.カラムA = テーブルB.カラムAの条件式。

    主キー同士や、主キーと外部キーを条件とするなら問題は起こりにくいと思いますが、

    NULLを許可している非キー属性のカラムを結合の条件とする場合は、注意が必要です。

    その注意というのは、テーブルA.カラムA、 テーブルB.カラムAの両方に「NULL」がセットされている場合、

    条件式「テーブルA.カラムA = テーブルB.カラムA」の結果は、常に「FALSE」となってしまう事です。

    もちろんテーブルA.カラムAには値がセットされており、

    テーブルB.カラムAはNULLという場合は「FALSE」と判定される事は、イメージしやすいと思います。

    ただSQLの世界では、「NULL = NULL」は「FALSE」となります。

     

    この事を忘れて、最近ハマってしまった事を例に挙げると、

    1.「テーブルHOGEに対するUPDATEを実行する前に、テーブルHOGEの内容をテーブルTEMPにすべてINSERT。
     (もちろんテーブルTEMPはTRUNCATE TABLE済み)」

    2.「テーブルHOGEにUPDATEを実行。」

    3.「テーブルHOGEとテーブルTEMPの差を取得する為に、主キーを条件に2つのテーブルを結合し、
      変更対象のカラムが一致しない行を選択。」
     (対象のRDBMSがMySQLだったので、EXCEPT演算子やMINUS演算子が利用できませんでした。)

    4.「3.の結果から変更結果を表示する」

     

    という処理だったのですが、3.で更新されていない行まで選択される現象が起こりました。

    色々調査した結果、変更対象のカラムにNULLがセットされており、「NULL = NULL」が「FALSE」と判定して、

    変更前と変更後のカラムが一致しないと判断しておりました。

     

    このような場合、普段からNOT NULL制約を設ける事が最良かと思いますが、

    すでに稼動してしまったデータベースに対しては、NVL関数やIFNULL関数を使用して、

    NULLを空文字などに置換する必要があります。

    IFNULL(テーブルA.カラムA, ”) = IFNULL(テーブルB.カラムA, ”)」等。

    やっぱり、NULLは混乱を招く元になりますね。

    Excel - 「*」と「?」の検索 -

    こんにちは、Eguchiです。

    今日は、マイクロソフトのExcelでふと忘れがちなことを発見したので、書き残して
    おきます。

    Excelの標準のツールバーにある「編集」→ 「検索」機能があるのをご存知の方は
    多いと思います。

    これで検索や置換を行う際に調べるキーワードを例えば、47都道府県名が入ったシート
    から、「都」だけのものを取り出したいとします。

    この際、よく「*都」として検索すれば、「京都」や「東京都」がヒットします。
    これは「*」がワイルドカードとして働き、「~都」に一致するデータを検索することが
    できるからです。

    では、ここで問題。

    「*」を文字列として、検索する場合は??

    ワイルドワードとして検索している場合では、それは「*(アスタリスク)」という
    記号文字列として検索はしてくれません。

    そこで、「*(アスタリスク)」自体を検索したい場合は、「~(チルダ)」をつけて
    検索を行います。

    この場合は「~*」としてアスタリスクの直前で検索すれば、文字列として検索することが
    できます。
    これと同様に「?」記号でも同じ検索方法を利用することができます。

    YahooUI - パネル の利用-

    こんにちは、Eguchiです。

    近頃、YahooUIを使わないと行けないケースが増えてきています。
    そこで、今日はライブラリの機能の1つパネルについて説明します。

     

    YahooUIライブラリの基本的な設定等は、以前お話したかと思いますので、省略します。

     

    今回のサンプル例として
    1.HTML画面内のボタンをクリック
    2.同画面にYahooUIのパネルで作った画面が表示
    といったものを作成します。

     
    まずは呼び出し側の、HTML側の例。ポイントは2つです。
    ①.パネルを呼び出すボタンを作る。
    ②.パネルとして呼び出す画面を呼び出し側のHTMLに埋め込む

     

    ボタンは、「<input type=”button” value=”サンプル” onclick=”samplePanel(’sampleId’);” > 」
    といった感じでパネルを呼び出します。
    ここでJavaScriptのメソッドに与えている引数は②のHTMLオブジェクトのID属性です。

     

    続いて②の埋め込みHTML(パネル部分)ですが、これはHTMLで好きに作成して下さい。
    ここで重要なのは、このパネル部分にする大外の領域を

    <div id=”’sampleId’” style=”display:none”></div>で囲むことです。

    これにより、初回表示時はパネルとなる部分のソースは見えなくなります。

     

    次にボタンを押してからのJavaScriptの動きですが下記に例を記載いたします。

    function samplePanel(id){

        var obj = document.getElementById(id);                       //まずは隠していた部分の非表示を表示
        obj.style.display = “block”;
       
        var panelObj = new YAHOO.widget.Panel(id,{
            width:”400px”,   //横幅
            height:”180px”,   //縦幅
            fixedcenter:true,  //センタリング(true:false)
            constraintoviewport:true,      //
            underlay:”none”,        //パネルの影(shadow,none,matte)
            modal:false,                  //モーダルモード(true:false)
            close:false,                    //クローズボタンの表示、非表示(true:false)
            visible:true,                 //パネルの表示、非表示(true:false)
            effect:{effect:YAHOO.widget.ContainerEffect.FADE,duration:0.25},      //パネル表示、非表示時のエフェクト(ここではフェードエフェクトをしてます)
            draggable:true}    //パネルのドラッグ&ドロップ設定(true:fasle)
        );
        panelObj.setHeader(”ヘッダー部分のコメント”);        //パネルのヘッダー部分の設定
        panelObj.render();
        panelObj.show();

    }

     

    と、上記のような感じで定義すると、簡単なパネルが表示されます。

    他にも色々設定が細かいので、調べてみるといいかもです。

    http://journal.mycom.co.jp/articles/2008/05/23/yahoouipanel/index.html(参考したサイト)