Manual

Class

클래스의 구조

by TheVOS posted Oct 03, 2019
?

Shortcut

PrevPrev Article

NextNext Article

Larger Font Smaller Font Up Down Go comment Print
?

Shortcut

PrevPrev Article

NextNext Article

Larger Font Smaller Font Up Down Go comment Print
Extra Form
Original source http://tcpschool.com/php/php_class_structure

클래스의 구조

PHP에서 클래스는 class 키워드를 사용하여 다음과 같이 선언합니다.

문법

class 클래스이름
{
    클래스의 프로퍼티과 메소드의 정의;
}

 

PHP에서 클래스의 이름을 생성할 때는 반드시 다음 규칙을 지켜야만 합니다.

 

1. 클래스의 이름은 숫자와의 구분을 빠르게 하려고 숫자로 시작할 수 없습니다.

2. 클래스의 이름은 영문자(대소문자), 숫자, 언더스코어(_)로만 구성됩니다.

3. 클래스의 이름 사이에는 공백이 포함될 수 없습니다.

4. 클래스의 이름은 대소문자를 구분합니다.

5. PHP에서 미리 정의한 예약어(reserved word)는 클래스의 이름으로 사용할 수 없습니다.

 

클래스는 클래스만의 상수와 변수를 가질 수 있으며, 이것을 프로퍼티(property)이라고 합니다.

또한, 메서드(method)라고 불리는 연산을 정의할 수도 있습니다.


생성자(constructor)

클래스는 새로운 객체를 생성할 때마다 생성자(constructor)라는 메서드를 호출합니다.

 

생성자는 객체가 생성될 때마다 호출되어 해당 객체의 프로퍼티를 초기화하거나, 필요한 다른 객체를 생성하는 등의 초기화 작업을 수행합니다.

생성자는 다른 메소드와 같은 방식으로 선언되며, 매개변수를 가질 수도 있습니다. 

 

PHP에서 생성자의 이름은 __construct()로 정해져 있습니다.

이러한 생성자는 객체가 생성될 때마다 자동으로 호출되므로, 사용자가 직접 호출할 필요가 없습니다.

문법

class 클래스이름
{
    function __construct ( 매개변수1매개변수2, ...)
    {
        생성자가 호출될  실행될 코드;
    }
}


소멸자(destructor)

소멸자(destructor)는 생성자와는 반대로 해당 객체를 더는 사용하지 않아 삭제할 때 호출합니다. 

PHP에서 소멸자의 이름은 __desturct()로 정해져 있으며, 매개변수를 가질 수 없습니다.

문법

class 클래스이름
{
    function __desturct ( )
    {
        소멸자가 호출될  실행될 코드;
    }
}


Facebook Comment 


  • Q: [EC-CUBE 2系] EC-CUBEをインストールする TheVOS 2019.12.10
    A:

    EC-CUBEを利用することになりそうなので、ひとまずEC-CUBEをレンタルサーバーにインストールしてみました。その手順備忘録です。

    EC-CUBEをダウンロードする

    EC-CUBE公式サイトからファイルをダウンロードします。
    2019年12月時点で最新バージョンは、2.13.5です。なのでダウンロードしたファイルは eccube-2.13.5.zipでした。
    screencapture-ec-cube-net.jpg
    ダウンロードするには、EC-CUBEメンバーである必要があります。登録は無料なので迷わず登録しました。

    補足ですが、バージョンによっては不具合修正ファイルがあることもあるようなので、その場合はその不具合修正ファイルもダウンロードしておきます。(今回はありませんでした。)

    EC-CUBEのファイルを配置する

    ダウンロードしたファイルは圧縮ファイルなのでとりあえず解凍します。
    そして、サーバーに配置する前に少し準備します。

    解凍すると以下のフォルダが存在すると思います。
    /data
    /docs
    /html
    /test
    /tests
    必要になのは「data」「html」の2つだけです。
    (不具合修正ファイルがある場合は上書きしてください。)

    これから構築するサイトのURLを「http://ドメイン/html」ではなく「http://ドメイン/」としたいので、「data」フォルダを丸ごと「html」フォルダ直下に移動します。
    その移動に伴い、html/define.phpを修正します。

    (修正前)

    1
    define("HTML2DATA_DIR", "/../data/");

    (修正後)

    1
    define("HTML2DATA_DIR", "/data/");

    次に「html」フォルダ直下にある.htaccessを削除します。

    ↓↓↓↓↓ 重要 ↓↓↓↓↓
    このままでは、dataフォルダにWEbからアクセスできてしまうため、とっても危険です。
    例えばlogファイルが丸見えになってしまうので、管理画面のログインIDやサーバーのパスや何のプラグイン使ってるかーなど、いろいろとデータが取れてしまうのです。(他にもいろいろ問題アリ。)
    そこで、dataフォルダ直下に以下を記述した.htaccessを配置します。

    1
    2
    order allow, deny
    deny from all

    ほんとは、dataフォルダはhtmlフォルダ内じゃなくて、ルートディレクトリ外に配置できる方が理想です。
    今回はどうしてもそれが出来ない環境の場合を例にしています。
    ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

    ここまで出来たら、サーバーに配置します。
    配置する場所はサーバーによって異なりますが、たいていはApacheのドキュメントルート直下に「html」フォルダ内のフォルダ、ファイル全てを配置します。

    データベースを作る

    EC-CUBEはデータベースを必要とするのでデータベースを事前に準備します。
    PostgreSQLかMySQLを使用することができます。私はphpMyAdminを使ってMySQLを作成しました。
    後で必要になるので、データベース名、MySQLユーザー名、MySQLパスワード、ホスト名をメモしておきます。

    EC-CUBEをインストールする

    「http://ドメイン/」にアクセスします。以下の画面が表示されたら「次へ進む」ボタンを押します。
    eccube-ins-02

    チェック結果が表示されます。成功していれば「次に進む」ボタンを押します。
    eccube-ins-03

    必要なファイルのコピーが開始されます。これも成功していれば「次に進む」ボタンを押します。
    eccube-ins-04

    ECサイトの設定をします。
    純国産のCMSというだけあって説明が丁寧です。さすがです。必要事項を入力して次へ進みましょう。
    eccube-ins-05

    データベースの設定です。
    事前に準備したデータベースの情報を入力します。DBの種類を間違えないようにしましょう。
    入力できたら「次へ進む」ボタンを押します。
    eccube-ins-07

    データベースの初期化です。
    eccube-ins-08
    eccube-ins-09

    デバッグのために情報提供を依頼されます。無難に「はい(推奨)」にしました。「いいえ」にしたらどうなるかは、試してないのでわかりません。
    eccube-ins-10

    インストール完了です。管理画面ログインにすすみます。
    eccube-ins-11

    ここで画面上部に警告が出ます。install/index.phpを削除しろと言っています。おとなしく従いましょう。
    eccube-ins-12

    ファイルを削除するとログイン画面から警告が消えるので、改めて管理画面にログインします。
    eccube-ins-13

    これにて終了です。

    Facebook Comment 

  • Q: [CSS] CSS オブジェクトフィットプロパティ TheVOS 2019.12.04
    A:

    object-fit 속성은 IMG, VIDEO 태그의 크기를 컨테이너에 맞게 자정하는데 사용됩니다.


    브라우저 지원

    테이블의 숫자는 완전히 속성을 지원하는 최초의 브라우저 버전을 지정합니다.

    Propertyicon-chrome1.png icon-edge.png icon-firefox1.png icon-safari1.png icon-opera1.png
    object-fit31.016.036.07.119.0

    정의(Definition)

    • object-fit 속성은 <img>, <video> 태그의 크기를 정의합니다.

    문법(Syntax)

    object-fit: fill | contain | cover | scale-down | none

    속성(Property)

    속성값설명
    fill컨텐츠 사이즈 크기에 맞게 설정합니다.
    contain컨텐츠의 가로 값을 기준으로 맞게 설정합니다.
    cover컨텐츠 화면 사이즈에 맞게 설정합니다.
    scale-down컨텐츠 크기 보다 작게 설정합니다.


    Original

    FILL

    CONTAIN

    COVER

    NONE

    SCALE-DOWN




    object-fit: fill;
    object-fit: contain;
    object-fit: cover;
    object-fit: none;
    object-fit: scale-down;
    


    Facebook Comment 

  • Q: [CSS] Css 텍스트 외곽선 처리하기, Stroke TheVOS 2019.11.28
    A:
    CSS를 사용하여 텍스트에 외곽선, stroke 효과를 주는 방법을 알아봅니다.

    외곽선은 텍스트를 강조하는 효과적인 방법입니다. 간단하게 css를 사용하여 사용하는 것이 가능한데 가장 간단한 방법은 아래처럼 -webkit-text-stroke를 사용하는 방법입니다.

    -webkit-text-stroke: 1px #000


    다만, 이 방법은 매우 편리한 방법이지만 아쉽게도 표준 방법은 아니라 웹킷 및 모질라 계열의 브라우저에서만 적용됩니다. 사용할 경우 아래처럼 css에 적용하시기 바랍니다.
    .text-stroke {
      -webkit-text-stroke: 1px #000;
    }

    이제 텍스트에 외곽선이 선명하게 나타납니다.

    그렇다면 또 다른 방법을 알아봅니다.


    # -webkit-text-stroke 크로스 브라우징 방법아래와 같은 방법을 사용하면 텍스트음영효과인 text-shadow를 이용하여 비슷한 효과를 만들 수 있습니다. 아래 코드를 봐주세요.

    .text-stroke {
        color: #f00;
        text-shadow:
        -1px -1px 0 #000,
        1px -1px 0 #000,
        -1px 1px 0 #000,
        1px 1px 0 #000;  
    }


    이 방법은 text-shadow가 적용되는 대부분의 브라우저에서 구현됩니다. 매우 효과적인 방법입니다.

    # 실제 외곽선 적용된 예제보기
    만약 아래와 같은 html에 위 css를 적용하여 외곽선을 직접 구현해보겠습니다.

    <span class="text-stroke">THEVOS</span>


    위 코드의 실행결과는 아래와 같습니다.

    THEVOS

    Facebook Comment 

  • Q: [EC-CUBE 4.x] EC-CUBE 4를 설치했을 때 설정 한 데이터베이스 암호는 어디에 저장되는 것입니까? TheVOS 2019.11.14
    A:

    설치 한 디렉토리에 .env라는 파일이 있습니다.

    거기에 DATABASE_URL라는 항목이 있습니다.


    「 DATABASE_URL = mysql://사용자 이름:암호@호스트 이름/데이터베이스 이름 」 형식으로 저장되어 있습니다.

    Facebook Comment 

  • Q: [EC-CUBE 2系] EC-CUBE2.13カスタマイズ:新しいページを追加する TheVOS 2019.11.11
    A:

    EC-CUBEで新しいページを追加する方法として、管理画面で追加して、そのページのURLを任意に変更する手順をメモ。

    管理画面からページを追加する

    管理画面でデザイン管理>PC>ページ詳細設定を開き、必要事項を入力して登録するボタンを押下。
    ※スマホ、モバイルもそれぞれ同様です。
    EC-CUBE-add-page-01

    これにより以下の追加が行われます。
    1)/html/user_data/sample.phpが生成される。
    ※sample.phpは登録した任意のファイル名
    ※処理はこのファイルに記述していきます
    2)/data/Smarty/templates/(テンプレート名)/user_data/sample.tplが生成される。
    ※管理画面から入力した内容が入ります。
    3)dtb_pagelayoutテーブルにこのページ情報が1レコード追加される。

    作成されたページのこの時点では以下のパスで確認できます。
    http://www.example.com/html/user_data/sample.php
    このままではイケテないので以下になるように変更していきたいと思います。
    http://www.example.com/html/sample/

    追加したページのURLを変更する

    phpファイルを移動する

    まず生成されたphpファイルを以下に移動します。フォルダを新規作成してファイル名も変更します。
    /html/sample/index.php

    DBを書き換える

    dtb_pagelayoutテーブルのurlフィールドをsample/index.phpに変更する。
    これで、URLの変更ができました。

    ちなみに、dtb_pagelayoutテーブルの中身ですが、おそらくこんな感じ。
    device_type_id・・・「10」はPC用のページという意味
    page_id・・・同じdevice_type_idで重複しないID
    page_name・・・ページ名(管理画面で表示している名前)
    url・・・ページのURL
    filename・・・tplファイルの保管場所
    edit_flg・・・削除可能フラグ

    注:インストールされた環境によってパスは異なります。一般的なパスで紹介しています。

    2014.09.08 追記
    追加したページのURLを変更した場合は、ページを更新するときに管理画面のデザイン管理>PC>ページ詳細設定から編集できなくなります。
    編集してしまうとdtb_pagelayoutテーブルのurlフィールドがデフォルトに戻ってしまうからです。
    更新はテンプレートを直接しなくてはなりません。
    んー、イマイチ?URLを変更しても管理画面から更新できる方法ないかなー?

    Facebook Comment 

  • Q: [EC-CUBE 3系] 관리 화면의 사이드 메뉴에 항목 추가하는 방법 TheVOS 2019.11.11
    A:

    EC-CUBE3에서는 관리 화면의 사이드 메뉴에 쉽게 메뉴를 추가 할 수 있습니다.

    관리 화면에 메뉴 추가

    외형 수정이므로 템플릿 (twig)를 편집 ...라고 생각했는데, 수정할 필요가있는 것은 ServiceProvider입니다.
    실제로 ServiceProvider에서하지 않아도 좋다고 생각 합니다만,로드 된 적당한 ServiceProvider 다음의 설명합니다.

            $ app [ 'config'] = $ app-> share ($ app-> extend ( 'config', function ($ config) {
                $ nav = array (
                    'id'=> 'admin_new_menu'
                    'name'=> '새 메뉴'
                    'url'=> 'admin_new_menu'
                    'has_child'=> 'false'
                    'icon'=> 'cb-chart'
                    'child'=> array (
                        array (
                            'id'=> 'xx_submenu1'
                            'url'=> 'xx_submenu1'
                            'name'=> '하위 메뉴 1'
                        ),
                    ),
                );
    
                $ config [ 'nav'] [] = $ nav;
    
                return $ config;
            }));

    이렇게 app.config.nav 메뉴 배열을 추가하여 메뉴를 늘릴 수 있습니다.
    반대로 필요없는 항목이 배열로부터 삭제 해 주면 제거 할 수 있습니다.

    EC-CUBE3를 이용하시는 분은 꼭보세요.

    Facebook Comment 

  • Q: [EC-CUBE 2.x] EC-CUBE에서 모든 페이지에서 로그인 체크하기 TheVOS 2019.11.11
    A:

    EC-CUBE는 Ver 2.12.6 환경입니다.


    지정 방법

    EC-CUBE는 로그인 판정 결과를 tpl_login라는 변수로 설정하고 일부 페이지가 기본적으로 존재합니다.

    예를 들어, 아래와 같이 소스를 grep하면 tpl_login에 값을 설정하는 부분을 찾을 수 있습니다.

    1
    2
    3
    4
    5
    6
    7
    $ grep -rn "\$this\->tpl_login =" *
    data/class/pages/products/LC_Page_Products_Detail.php:240:            $this->tpl_login = true;
    data/class/pages/frontparts/bloc/LC_Page_FrontParts_Bloc_Login.php:43:        $this->tpl_login = false;
    data/class/pages/frontparts/bloc/LC_Page_FrontParts_Bloc_Login.php:72:            $this->tpl_login = true;
    data/class/pages/shopping/LC_Page_Shopping_Payment.php:95:            $this->tpl_login = '1';
    data/class/pages/shopping/LC_Page_Shopping_Confirm.php:129:            $this->tpl_login = '1';
    data/class/pages/cart/LC_Page_Cart.php:200:            $this->tpl_login = true;

    위의 이름에서 짐작이 붙는 것처럼, 상품 상세 페이지 로그인 블록, 장바구니 페이지, ... 등 특정 페이지를 표시 할 때 사용되는 클래스인데,이 페이지에서는 변수 tpl_login에 설정된 로그인 있는지 (true) 아닌지 (false) 결과에 따라 다음과 같이 템플릿의 표시를 분리 할 수 ​​있습니다.

    1
    2
    3
    4
    5
    <!--{if $tpl_login}-->
    ログイン中です。
    <!--{else}-->
    ログインしていません。
    <!--{/if}-->

    그런데, 이것을 특정 페이지에 한정하지 않고 어떤 페이지에서도 사용할 수 있도록하자.

    페이지 볼 때마다 호출되는 LC_Page라는 기본 클래스 LC_Page (data/class/pages/LC_Page.php)가 있습니다. 그 확장 클래스인 LC_Page_Ex (data/class_extends/page_extends/LC_Page_Ex.php)에 다음과 같은 코드를 추가합니다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public function init()
    {  
        parent::init();
        // ログイン判定
        $objCustomer = new SC_Customer_Ex();
        if ($objCustomer->isLoginSuccess() === true) {
            $this->tpl_login = true;
        }  

    이제 어떤 페이지에서나 tpl_login에 로그인 판정 결과가 저장 되도록 되었습니다.

    마찬가지로 LC_Page_Ex에 어떤 처리든 추가하면 전체 페이지 공통으로 정보를 설정하는 것이 가능합니다.  

    알아두면 유용한 곳이 많을 듯합니다.

    Facebook Comment 

  • Q: [EC-CUBE 2系] イベントセット販売プラグインマニュアル TheVOS 2019.11.07
    A:
    • プラグイン登録
      1. ファイルの選択ボタンをクリックします。
      2. 登録するファイル(EventSetSale.tar.gz)を選択し、開くをクリックします。
      3. インストールのボタンをクリックして、待って、インストールを待ちます。
      4. 下の1-2画面の①の赤長方形のボックスのように表示されたら、通常のインストールがされました。
        1-2.インストール完了画面:通常のインストールが完了した画面
      5. プラグインの基本的な設定をするために②プラグインの設定をクリックして設定画面を開いて、各値を入力して設定します。
      6. インストールされてプラグインを動作させるために1-2画面の③有効チェックボックスをクリックしてチェック 表示をします。

    Facebook Comment 

  • Q: [EC-CUBE 4系] EC-CUBE4系で管理画面に新規メニュー項目を追加する方法 TheVOS 2019.10.28
    A:

    今回は商品管理の一番下に新規メニュー項目を追加することを考えます。
    まずメニューから開けるページが必要ですのでコントローラーを作成し、新しいページを作った後でそのページをメニューに追加してみましょう。今回はeccube_nav.yamlを編集するもっとも簡単な方法をご紹介します。

    管理画面に新規ページを作る方法は下記URLで紹介しています。
    管理画面に2ステップで新規ページを作る方法

    それでは、このページを商品管理のメニューに追加してみます。

    初期状態での管理画面のメニュー一覧はapp/config/eccube/packages/eccube_nav.yamlに配列として記載されています。
    商品のメニュー部分は下記のようになっています。

    parameters:
        eccube_nav:
            product:
                name: admin.product.product_management
                icon: fa-cube
                children:
                    product_master:
                        name: admin.product.product_list
                        url: admin_product
                    product_edit:
                        name: admin.product.product_registration
                        url: admin_product_product_new
                    class_name:
                        name: admin.product.class_management
                        url: admin_product_class_name
                    class_category:
                        name: admin.product.category_management
                        url: admin_product_category
                    product_tag:
                        name: admin.product.tag_management
                        url: admin_product_tag
                    product_csv_import:
                        name: admin.product.product_csv_upload
                        url: admin_product_csv_import
                    category_csv_import:
                        name: admin.product.category_csv_upload
                        url: admin_product_category_csv_import
                    #商品管理に新規メニュー追加

    category_csv_importの下に次のように追記することでメニューを追加することができます。

    product_new_menu:
        name: 新メニュー
        url: admin_new_menu

    new_menuはメニューにつけるID名で、このメニューをアクティブにしたい時にtwigから指定します。
    nameは表示する名称
    urlはコントローラーのRouteで指定したURLの名前です。

    動作検証

    これで管理画面にアクセスするとカテゴリCSV登録の下に新規メニューが追加されました。twigでメニューの位置を指定しているのでアクティブ表示になっています。

    メニュー追加

    eccube_nav.yamlを編集するとバージョンアップの際に上書きされてしまう可能性があります。
    大きなカスタマイズをするとバージョンアップできない可能性も高いですが、バージョンアップをご検討の方はEccubeNav(NavCompilerPass)の仕組みを利用するか、app/config/eccube/packages/prodなどに複製して用いると良いかもしれません。

    Facebook Comment 

  • Q: [EC-CUBE 2.x] EC CUBEで商品ごとに支払い方法を簡単に分ける TheVOS 2019.10.28
    A:
    EC CUBEで支払い方法を分けるのに大きなカスタマイズが必要だと思っていましたが、
    以下の設定で簡単に振り分けが出来ましたのでご紹介します。

    まずEC CUBE管理画面にログインし、システムデータ>マスターデータに進みます。
    マスターデータから「mtb_product_type」を選択します。

    ffd01.JPG
    デフォルトでは1と2が設定されていますので、追加のデータにIDと値を記載します。

    ffd02.JPG

    追加できたら基本情報>支払い方法に進み任意の設定を追加します。ffd03.JPG

    その後配送方法設定に進み、それぞれの取扱商品種別&取扱支払方法を設定した配送方法を作ります。
    同じ名称は設定できないようなので「ゆうパック」「郵パック」のようにしました。

    ffd04.JPG
    ffd05.JPG

    もし別々の商品を同じカゴにいれた場合は別々に決済をしてもらう形になります。
    カスタマイズなしでここまでできるのは便利だな~とおもいました!

    Facebook Comment 

  • Q: [EC-CUBE 2系] 2.13系 ソフトウェア要件 TheVOS 2019.10.11
    A:
    分類 ソフトウェア 動作確認済み
    WEBサーバ IIS 7.0~
    Apache 2.0.x~ 2.2.x~
    言語 PHP 5.2~
    データベース PostgreSQL 8.1.4~ 9.x~
    MySQL 5.0.x~

    必須PHPライブラリ

    • pgsql / mysql
    • gd
    • freetype2
    • mbstring
    • zlib
    • ctype
    • spl (PHP 5.3.0 未満の場合)
    • session

    推奨PHPライブラリ

    • JSON(PHP5.2以降でオーナーズストアを使用する場合は必須)
    • xml(プラグイン機能を使用する場合は必須)
    • OpenSSL
    • cURL
    • hash
    • mhash (PHP 5.3.0 未満の場合)
    • mcrypt
    • zip

    Facebook Comment 

  • Q: [EC-CUBE 2系] ECCUBE 2.13のインストール方法をスクリーンショット付きでわかりやすく徹底解説! TheVOS 2019.10.10
    A:

    EC-CUBE v2.13 インストール에 대한 이미지 검색결과


    EC-CUBE」とは、ECサイトに必要なカート機能や決済機能がパッケージ化されている、無料のツールです。ECサイトを運営したことがある人なら、きっと知っている人も多いはず。あとはWebサーバーさえあれば、わりと簡単にECサイトを立ち上げることができます。これからECサイトをはじめる方向けに、EC-CUBE バージョン2.13のインストール方法を、各画面のスクリーンショット付きでわかりやすく解説します。


    まずはダウンロード

    EC-CUBEサイトから、ZIPファイルをダウンロードしましょう。(この記事では、バージョンは2.13.2です。)

    なお、ダウンロードには会員登録が必要です。

    ECCUBEダウンロード

    つづいてメンバー登録

    ECCUBE 新規メンバー登録

    「eccube-2.13.2.zip」がダウンロードできたら、解凍してみましょう。
    すると、下記のようにいろいろなファイルが入っているはずです。
    このうち「data」と「html」の2つだけを、Webサーバーにアップロードしましょう。

    ECCUBE解凍フォルダ

    アップロード

    アップロードする前に、FTPソフトの設定でアップロード時のパーミッションを指定しておくことをおすすめします。
    ファイルは「644」、ディレクトリは「755」で設定しておきましょう。

    なお、data はセキュリティの面で、一般のユーザーから見えない階層にアップしたほうが良いです。

    私の場合はこんな感じ↓

    /root/data(=一般のユーザーは見れない領域)
    /root/www/html(=www配下は一般のユーザでも見れる領域)

    define.phpを編集

    私の場合は data と html が同階層でなくなったので、html 内の define.php を変更する必要があります。
    (data と html が同階層であれば、変更する必要はありませんので、このステップは飛ばして構いません)

    html ディレクトリから見た、dataディレクトリの相対パスを指定しましょう。

    [php]
    /** HTMLディレクトリからのDATAディレクトリの相対パス */
    define(‘HTML2DATA_DIR’, ‘../../data/’);
    [/php]


    データーベースを作成

    ECCUBEのインストール時にはデータベースの情報を求められますので、あらかじめ用意しておきましょう。

    ここでは私が利用しているさくらサーバーでのやり方をご紹介します。

    コントロールパネルにログイン。

    左ナビから「データベースの設定」を選択。

    データーベースの設定を選択

    「データベースの新規作成」を選択。

    データベースの新規作成を選択

     

    データーベースの情報を設定します。
    MySQLのバージョンは「5.5」、
    データベース名は、自由に命名してください。
    文字コードは「UTF-8」にします。

     

    データーベースの情報を入力

    これでデータベースが作成されました!


    ECCUBEのインストール画面

    先ほどアップした「html」ディレクトリにアクセスしてみましょう。

    パーミッションとdefine.phpのパスが正しく設定されていれば、次の画面が現れるはずです。

    ECCUBE インストール

    ECCUBE - インストール02

    ひとまず必須項目を入力していきます。
    これらの項目はインストール後でも管理画面から変更できます。

    ECCUBE - インストール04

    先ほど作成したデータベースの情報を入力していきます。
    さくらのコントロールパネルのデータベース一覧画面を参照してコピペしましょう。

    ECCUBE - インストール05

    つづいて、データベースの初期化を行います。(ちょっとドキドキ)

    ECCUBE - インストール06

    データベースの初期化に成功しました。

    ECCUBE - インストール07

    情報提供を送信するかをたずねられますが、これはどちらでも構いません。

    ECCUBE - インストール08

    以上でインストールが完了しました!

    ECCUBE - インストール09

    htmlディレクトリにアクセスすると、デフォルトのストアページが表示されるはずです。

    ECCUBE - 初期サイト

    次回は、管理画面から商品情報を変更してみます。

    Facebook Comment 

  • Q: [Class] 클래스의 사용 TheVOS 2019.10.03
    A:

    인스턴스의 생성

    클래스가 선언되고 나면, 선언된 클래스로부터 인스턴스를 생성할 수 있습니다.

    PHP에서는 new 키워드를 사용하여 인스턴스를 생성할 수 있습니다.

     

    이때 클래스 이름을 통해 생성자로 필요한 인수를 전달할 수 있습니다.

    문법

    $객체이름 = new 클래스이름 ( 인수1, 인수2, ...);


    클래스 멤버에 접근

    클래스의 프로퍼티에 접근하거나 메소드를 호출할 때는 화살표 기호(->)를 사용합니다.

     

    객체의 이름 뒤에 화살표 기호(->)를 붙이고, 접근하려고 하는 프로퍼티나 호출하고자 하는 메소드의 이름을 사용하면 됩니다.

    문법

    $객체이름 -> 프로퍼티 이름;

    $객체이름 -> 메소드이름;

     

    PHP에서는 프로퍼티와 메소드의 접근 범위를 제한할 수 있으므로, 클래스 외부에서는 접근 제어자에 따라 접근이 가능할 수도 있고 또는 불가능할 수도 있습니다.

     

    또한, 객체 내부에서 해당 인스턴스의 프로퍼티에 접근하고 싶을 때는 특별한 변수인 $this를 사용할 수 있습니다.

    $this 변수는 해당 인스턴스가 바로 자기 자신을 가리키는 데 사용하는 변수입니다.

    문법

    $this -> 프로퍼티이름;


    접근 제어(access modifier)

    객체 지향 프로그래밍에서 정보 은닉(data hiding)이란 사용자가 굳이 알 필요가 없는 정보는 사용자로부터 숨겨야 한다는 개념입니다.

    그렇게 함으로써 사용자는 언제나 최소한의 정보만으로 프로그램을 손쉽게 사용할 수 있게 됩니다.

     

    PHP에서는 클래스 멤버에 public, private, protected 키워드를 사용하여 각각의 멤버에 대한 접근 제어를 명시할 수 있습니다.

     

    public으로 선언된 멤버는 외부로 공개되며, 해당 객체를 사용하는 어디에서나 직접 접근할 수 있게 됩니다.

    private로 선언된 멤버는 외부로 공개되지 않으며, 해당 클래스의 멤버에서만 접근할 수 있습니다.

    protected로 선언된 멤버는 상위 클래스에 대해서는 public 멤버처럼 취급되며, 외부에서는 private 멤버처럼 취급됩니다.

    즉, 해당 클래스의 멤버와 해당 클래스를 상속받은 자식 클래스에서만 접근할 수 있습니다.

     

    var 키워드를 사용하여 클래스의 프로퍼티를 정의하면, 해당 프로퍼티의 접근 제어는 public으로 자동 정의됩니다.

    또한, 메소드를 작성할 때 접근 제어자를 생략하면 public으로 자동 정의됩니다.

    예제

    class ClassName
    {
        public $publicVar;
        private $privateVar;

        protected $protectedVar;

     

        public function __constructor ( )
        {
            $this -> publicVar = "public property<br>";

            $this -> privateVar = "private property<br>";

            $this -> protectedVar = "protected property<br>";

        }

     

        public function publicMethod ( )
        {
            echo "public method<br>";

        }
        protected function protectedMethod( )
        {
            echo "protected method<br>";
        }
        private function privateMethod( )
        {
            echo "private method<br>";
        }
    }


    $object = new ClassName ( );


    echo $object -> publicVar;      // 접근 가능
    //echo $object->protectedVar; // 접근 불가능
    //echo $object->privatev;     // 접근 불가능


    $object -> publicMethod( );      // 호출 가능
    //$object->protectedMethod(); // 호출 불가능
    //$object->privateMethod();   // 호출 불가능

    코딩연습 ▶

     

    위의 예제처럼 외부에서는 접근 제어자가 public으로 명시된 프로퍼티와 메소드만을 호출할 수 있습니다.


    정보 은닉(data hiding)

    클래스 외부에서는 접근 제어 때문에 private 멤버나 protected 멤버로는 직접 접근할 수 없습니다.

    하지만 public 메소드를 사용하면 해당 클래스의 private 멤버나 protected 멤버에도 접근할 수 있습니다.

     

    이렇게 public 메소드는 private 멤버나 protected 멤버와 프로그램 사이의 인터페이스(interface) 역할을 수행합니다.

    이렇게 외부에서 바로 데이터로 접근하지 못하게 하는 것을 정보 은닉(data hiding)이라고 합니다.

     

    예제

    class ClassName
    {
        private $privateVar;

     

     

        public function __constructor ( )
        {
            $this -> privateVar = "private property";

        }


        public function getValue ( )
        {
            return $this -> privateVar;
        }


        public function setValue ( $value )
        {
            $this -> privateVar = $value;
        }
    }
    $object = new ClassName ( );
    $object -> setValue ( "hello" ); // setValue() 함수를 통해 $private의 값을 변경할 수 있음.
    echo $object ->getValue;     // getValue() 함수를 통해 $private의 값을 출력할 수 있음.

     

     

    위의 예제는 클래스의 외부에서 public 메소드인 getValue()와 setValue() 메소드를 사용하여 해당 클래스의 private 멤버에 접근할 수 있음을 보여주고 있습니다.

    Facebook Comment 

  • Q: [Class] 클래스의 구조 TheVOS 2019.10.03
    A:

    클래스의 구조

    PHP에서 클래스는 class 키워드를 사용하여 다음과 같이 선언합니다.

    문법

    class 클래스이름
    {
        클래스의 프로퍼티과 메소드의 정의;
    }

     

    PHP에서 클래스의 이름을 생성할 때는 반드시 다음 규칙을 지켜야만 합니다.

     

    1. 클래스의 이름은 숫자와의 구분을 빠르게 하려고 숫자로 시작할 수 없습니다.

    2. 클래스의 이름은 영문자(대소문자), 숫자, 언더스코어(_)로만 구성됩니다.

    3. 클래스의 이름 사이에는 공백이 포함될 수 없습니다.

    4. 클래스의 이름은 대소문자를 구분합니다.

    5. PHP에서 미리 정의한 예약어(reserved word)는 클래스의 이름으로 사용할 수 없습니다.

     

    클래스는 클래스만의 상수와 변수를 가질 수 있으며, 이것을 프로퍼티(property)이라고 합니다.

    또한, 메서드(method)라고 불리는 연산을 정의할 수도 있습니다.


    생성자(constructor)

    클래스는 새로운 객체를 생성할 때마다 생성자(constructor)라는 메서드를 호출합니다.

     

    생성자는 객체가 생성될 때마다 호출되어 해당 객체의 프로퍼티를 초기화하거나, 필요한 다른 객체를 생성하는 등의 초기화 작업을 수행합니다.

    생성자는 다른 메소드와 같은 방식으로 선언되며, 매개변수를 가질 수도 있습니다. 

     

    PHP에서 생성자의 이름은 __construct()로 정해져 있습니다.

    이러한 생성자는 객체가 생성될 때마다 자동으로 호출되므로, 사용자가 직접 호출할 필요가 없습니다.

    문법

    class 클래스이름
    {
        function __construct ( 매개변수1매개변수2, ...)
        {
            생성자가 호출될  실행될 코드;
        }
    }


    소멸자(destructor)

    소멸자(destructor)는 생성자와는 반대로 해당 객체를 더는 사용하지 않아 삭제할 때 호출합니다. 

    PHP에서 소멸자의 이름은 __desturct()로 정해져 있으며, 매개변수를 가질 수 없습니다.

    문법

    class 클래스이름
    {
        function __desturct ( )
        {
            소멸자가 호출될  실행될 코드;
        }
    }


    Facebook Comment 

  • Q: [Class] 클래스와 객체의 기초 TheVOS 2019.10.03
    A:

    クラス(class)とオブジェクト(object)

    オブジェクト(object)とは、実生活では、我々が認識することができるもので理解することができます。

    これらのオブジェクトの状態(state)と行動(behavior)は、それぞれのプロパティ(property)とメソッド(method)に実装されます。


    また、オブジェクト(object)を作り出すための枠組みや設計図のような概念がまさにクラス(class)です。

    つまり、PHPでは、クラスを持っているオブジェクトを作成して使用します。


    次の例では、Carクラスのオブジェクト(object)を示す例です。


    クラス(class)

    - 車(Car)

    スポーツカー


    プロパティ(property)

    - $car->modelName = "フェラーリNYIAS"

    - $car->modelYear = 2012

    - $car->color = "黄色"

    - $car->maxSpeed = 206 mph


    メソッド(method)

    - $car->accelerate()

    - $car->brake()


    インスタンス(instance)

    - 私の車(myCar)


    自動車インスタンスは、すべて上記のようなプロパティとメソッドを持つでしょう。

    しかし、各プロパティの値はインスタンスにすべて異なります。


    プログラミングでインスタンス(instance)とは、メモリ上に作成されたオブジェクトを意味します。

    オブジェクト指向プログラミング(OOP、Object-Oriented Programming)

    オブジェクト指向プログラミングでは、すべてのデータをオブジェクト(object)として扱われ、オブジェクトがすぐにプログラミングの中心となります。

    これにより、コードの管理が容易になり、より少ない労力でも簡単にコードを変更すると、維持管理することができます。


    オブジェクト指向プログラミングが持つ特徴は次のとおりです。


    1. 抽象化(abstraction)
    2. カプセル化(encapsulation)
    3. 情報秘匿(data hiding)
    4. 継承性(inheritance)
    5. ポリモーフィズム(polymorphism)

    カプセル化は、すでに作成されたコードを変更せずに再使用することを目的とします。

    また、情報秘匿を介してオブジェクトの実際の実装内容を外部で知られないよう隠し、オブジェクトのインタフェースを介してのみデータにアクセスできるようにして、セキュリティを強化します。

    継承は、クラス間の階層関係を作って、論理的かつ体系的に他のクラスの機能とデータを使用できるようになります。

    また、ポリモーフィズムを介して一つの変数や関数の名前が、状況に応じて別の意味で解釈されることができるようになります。

    Facebook Comment 

  • Q: [EC-CUBE 2.x] EC-CUBE:SC_FormParamクラスによるパラメーターチェック方法 TheVOS 2019.10.03
    A:

    今お仕事で関わっているEC-CUBEですが、ネット上にはまだまだ情報が少ないです。

    例えばプラグイン作成でオリジナルフォームを作っても、SC_FormParamクラスを使って、どうやってチェックしたらいいのか調べてもなかなか出て来ません。
    そこで私が独自で調べた中から、少しづつ情報提供していきたいと思います。

    ※:EC-CUBEのバージョンは2.12.2のものをベースにしています。

    SC_FormParamの基本的な使い方

    SC_FormParamクラスを使うには、拡張先であるSC_FormParam_Exクラスをインスタンス化して利用します。 ここではPOSTされたデータを設定してみましょう。

    $objFormParam = new SC_FormParam_Ex();
    $objFormParam->setParam($_POST);
    

    次に、内容の検証ルールを追加します。
    ここでは例として名前(性、名)とメールアドレスを必須入力にし、メールアドレスはちゃんとした形式になっているもののみ受け入れるようにしてみます。

    $objFormParam->addParam('姓', 'sei', '', '', array('EXIST_CHECK','NO_SPTAB'));
    $objFormParam->addParam('名', 'mei', '', '', array('EXIST_CHECK','NO_SPTAB'));
    $objFormParam->addParam('メールアドレス', 'email', '', '', array('EMAIL_CHECK'));
    

    後半に挙げる「オプション」が必要な検証ルールについては、次のようにaddParam()の3番目の引数に設定します。

    //姓を3文字以内にしたい場合
    $objFormParam->addParam('姓, 'sei', 3, '', array('MAX_LENGTH_CHECK'));
    

    そして最後に検証作業。
    エラーがあると$arrErr変数にエラーが配列で格納されます。

    $arrErr = $objFormParam->checkError();
    

    検証ルールの最後のパラメーターにある配列型の文字のところがポイントなんですけど、ここに様々なルールを追加していくことでいろんな検証ルールを作ることができます。 以下に検証ルール一覧を載せてみたので実際に組み合わせて試してみてください。

    $objFormParam->addParam()の4番目の引数は入力値をmb_convert_kana()で変換するための変換オプション文字列を指定します。 変換オプションを指定した場合は、checkError()を実行する前に「$objFormParam->convParam()」を実行する必要があるので注意してください。

    SC_FormParam検証ルール一覧

    チェック項目 定数名 オプション エラー条件
    必須入力の判定 EXIST_CHECK   値の受け取りがない場合エラーを返す
    数字の判定 NUM_CHECK   入力文字が数字以外ならエラーを返す
    メールアドレス形式の判定 EMAIL_CHECK   メールアドレス形式でないならエラーを返す
    メールアドレスに使用できる文字の判定 EMAIL_CHAR_CHECK   メールアドレスに使用できない文字が含まれていたらエラーを返す
    携帯メールアドレスの判定 MOBILE_EMAIL_CHECK   SC_Helper_Mobile_Ex::gfIsMobileMailAddress()による判定結果でエラーを返す
    英字の判定 ALPHA_CHECK   入力文字が半角英字以外ならエラーを返す
    英数字の判定 ALNUM_CHECK   入力文字が英数字以外ならエラーを返す
    英数記号の判定 GRAPH_CHECK   入力文字が英数記号以外ならエラーを返す
    カタカナの判定 KANA_CHECK   入力文字がカナ以外ならエラーを返す
    カタカナの判定2 KANABLANK_CHECK   入力文字がカナ以外ならエラーを返す (タブ、スペースは許可する)
    URL形式の判定 URL_CHECK   URLを正規表現で判定する。デフォルトでhttp://があってもOK
    IPアドレスの判定 IP_CHECK   IPアドレスでない場合エラーを返す。改行コードが含まれている場合には配列に変換
    ドメインチェック DOMAIN_CHECK   ドメインの形式が正しくなければエラーを返す
    スペース、タブのみの判定 SPTAB_CHECK   スペース、タブ、改行のみの入力の場合エラーを返す
    スペース、タブの判定 NO_SPTAB   入力文字がスペース、タブ、改行を含んでいたらエラーを返す
    数字(非ゼロ)の判定 ZERO_CHECK   数値入力値で0が入力された場合エラーを返す
    ゼロで開始されている数値の判定 ZERO_START   0で始まる数値が入力されていたらエラーを返す
    ファイルの存在チェック FILE_EXISTS   入力パスのファイルが見つからなければエラーを返す
    ディレクトリ内のファイル存在チェック FIND_FILE ディレクトリ 指定ディレクトリ内に入力パスのファイルが見つからなければエラーを返す(デフォルトでIMAGE_SAVE_REALDIR)
    ディレクトリ存在チェック DIR_CHECK   入力されたパス文字のディレクトリが見つからなければエラーを返す
    ファイル名の判定 FILE_NAME_CHECK   入力文字が英数字,’_’,’-‘以外ならエラーを返す
    ファイル名の判定(アップロード以外の時) FILE_NAME_CHECK_BY_NOUPLOAD   入力文字が英数字,’_’,’-‘以外ならエラーを返す
    最大文字数制限の判定 MAX_LENGTH_CHECK 最大文字数 入力が指定文字数より大きいならエラーを返す
    最小文字数制限の判定 MIN_LENGTH_CHECK 最小文字数 入力が指定文字数未満ならエラーを返す
    桁数の判定 NUM_COUNT_CHECK 桁数 入力文字の桁数が指定の桁数でなければエラーを返す
    必須選択の判定 SELECT_CHECK   プルダウンなどで選択されていない場合エラーを返す
    小文字に変換 CHANGE_LOWER   入力文字を小文字に変換する
    ダウンロード用ファイルの存在チェック DOWN_FILE_EXISTS   DOWN_SAVE_REALDIR内に入力パスのファイルが見つからなければエラーを返す

    お役に立てば幸いです。

    Facebook Comment 

  • Q: [EC-CUBE Operation Manual] EC-CUBE2.12 運用マニュアル TheVOS 2019.09.29
    A:

    EC-CUBE 

    Ver2120 

    Ver2121 

    Ver2122 

    運用マニュアル

    2012年11月28日




    目次

    開店準備4
    基本情報設定4
    SHOPマスターの設定4
    特定商取引に基づく表記の登録5
    配送方法の設定6
    支払い方法の設定8
    ポイントの設定9
    受注受付メールの設定9
    会員規約の設定11
    郵便番号DB登録11
    SEO管理13
    定休日管理13
    商品登録14
    カテゴリーの登録14
    メーカーの登録15
    商品の登録15
    規格の登録19
    商品並び替え21
    運用22
    受注管理22
    受注管理22
    対応状況管理25
    会員管理26
    会員マスター26
    売上集計28
    売上集計の参照28
    メルマガ管理30
    テンプレート設定30
    配信内容設定32
    コンテンツ管理34
    新着情報管理34
    おすすめ商品管理36
    ファイル管理38



    目次

    ファイル管理38
    CSV出力設定39
    レビュー管理41
    レビュー管理41
    デザイン管理42
    レイアウト管理42
    ページ詳細設定45
    ブロック設定46
    ヘッダー / フッダーの編集47
    CSS設定48
    テンプレート追加49
    テンプレート設定50
    システム設定51
    ユーザ管理51
    バックアップ管理52
    プラグイン管理53




    Facebook Comment 

  • Q: [EC-CUBE 2系] 単体テストガイドライン TheVOS 2019.09.28
    A:

    本ガイドラインはEC-CUBEの単体テストをPHPUnitを使って行う上でのガイドラインを
    株式会社SHIFT様(http://www.shiftinc.jp/)のご協力によりまとめたものとなります。

    各クラス共通のガイドライン

    1. テストを含めたフォルダ構成

    テストコードを含んだフォルダ構成は以下のようになります。
    tests以下には、テストコード本体の他にテスト用のユーティリティや設定ファイル等が含まれます。

    build.xmlテストやインスペクションを行うための設定ファイルです。
    tests
    ├phpunit.xmlPHPUnitで使う各種設定を記載したファイルです。
    SVN上にはphpunit.xml.baseというファイルがありますが、ローカルではこれをコピーしてphpunit.xmlを作成してください。
    ├ruleset.xmlPHP_CodeSniffer(インスペクションツール)用の設定ファイルです。
    ├require.phpテストに必要なファイルをインクルードするためのクラスです。
    SVN上にはrequire.php.baseというファイルがありますが、ローカルではこれをコピーしてrequire.phpを作成してください。
    └classテスト用のクラスを格納するディレクトリです。
     ├Common_TestCase.php他のテストクラスの基底となるクラスです。
     ├replaceテスト用に実装を入れ替えているクラスを格納するディレクトリです。
     └test/utilテスト用のユーティリティを格納するディレクトリです。

    テストコードはそれぞれ対応するソースコードと同じ階層に保存します。

    2. テストの実行方法

    2.1.  実行の準備(初回のみ)

    単体テストを実行するためには、ローカルの環境にPHPUnitをインストールしておく必要があります。
    また、インクルードパス等をローカルの環境に合わせて書き換えるため、SVNに含まれているファイルをコピーしてローカル用の設定ファイルを作成する必要があります。
    手順は下記の通りです。

    • tests/phpunit.xml.baseをコピーしてtests/phpunit.xmlを作成します。
    • <filter><blacklist>タグ以下の「/usr/local/lib」の部分を、ローカルで使われる各種ライブラリが含まれているパスと置換します。
      • この設定はどのファイルをテストのカバレッジ測定の対象にするかを設定するためのものなので、設定をし直さなくても単体テスト自体は問題なく動作します。
    • tests/require.php.baseをコピーしてtests/require.phpを作成します。
    • PHPUnitのモジュールが使用できるように、インクルードパスを設定します。

    tests/phpunit.xml、tests/require.phpはsvn:ignoreに設定されているため、自由に書き換えてもコミットはされません。

    2.2.  実行

    全体のテストを行う場合には、phingのtestターゲットを実行します。
    テストの内容はbuild.xmlの中に定義されているため、実際にはphpunitコマンドが発行されます。

    % phing test
    

    テストが完了すると、結果がreportsディレクトリ以下に出力されます。

    • reports/tap.log TAP形式のテスト結果
    • reports/unitreport.xml xUnit形式のテスト結果
    • reports/coverage/coverage.xml カバレッジ測定結果のXML(主にJenkinsで処理するためのものなので気にしなくて良いです)
    • reports/coverage/.html カバレッジ測定結果のHTML

    個々のテストを行う場合には、テスト対象のディレクトリを指定してphpunitコマンドを実行します。
    標準出力ですぐにテスト結果を確認したい場合にはこちらのやり方のほうが良いでしょう。

    % phpunit –c tests/phpunit.xml tests/class/pages/LC_Page/LC_Page_InitTest.php
    % phpunit –c tests/phpunit.xml tests/class/pages
    

    下の例のようにディレクトリを指定した場合には、ディレクトリ以下にあるテストケースが実行されます。

    また、--colorsオプションを付けると、結果が色付きで表示され見やすくなります。

    % phpunit --colors –c tests/phpunit.xml tests/class/pages/LC_Page/LC_Page_InitTest.php
    

    カバレッジを測定したい場合には、専用のオプションを指定します。

    % phpunit -c tests/phpunit.xml --coverage-html reports/coverage tests/class/pages/LC_Page/LC_Page_InitTest.php
    

    3. テストクラスの構成

    テストクラスは、基本的にtests/class/Common_TestCase.phpを継承して作成します。
    Common_TestCaseの中には、次節で述べるAssertionを一度に行うverify()関数や
    テストの開始時と終了時にDBの準備・後片付けを行うsetUp()/tearDown()関数が含まれています。
    個々のテストクラスでは、Common_TestCaseのsetUp()/tearDown()の処理に必要な処理を追加して使います。
    また、テストに使用するユーティリティクラスもCommon_TestCaseでまとめてrequireします。

    <?php
    SampleTest extends Common_TestCase {
    
      protected function setUp() {
        parent::setUp();
         // 個々のテストケースで必要な処理
      }
    
      protected function tearDown() {
        // 個々のテストケースで必要な処理
        parent::tearDown();
      }
      public function testFunctionName_❍❍の場合_△△になる() {
        $this->expected = array('hoge', 'fuga');
        $this->actual = array();
        $this->actual[0] = functionName('a');
        $this->actual[1] = functionName('b');
    
        $this->verify();
      }
    }
    

    4. Assertion(期待値の確認)の方法

    PHPUnitにはassertEquals()、assertTrue()など様々な期待値の確認用funcitonが存在します。
    これらを細かく使用してテストの期待値を確認することもできますが、複数のasseritionを並べると
    最初の方で失敗した場合に後のassertionが実行されず、全体の修正までに時間がかかってしまう場合があります。
    これを防ぐため、基本的に期待値と実際の結果はarrayに格納して一度でassertできるようにします。
    もちろん、それぞれの値が1つずつの場合はarrayに入れなくても構いません。

    <?php
    protected function verify($msg = null) {
      $this->assertEquals($this->expected, $this->actual, $msg);
    }
    
    public function testHoge() {
      $this->expected = array(1, "山田", "太郎");
      // テスト対象を実行して$actualに結果を格納
      $this->verify();
    } 
    

    5. テストfunctionの分け方

    原則として、1つのテストfunctionで1つの条件をテストします。

    • 良い例
      <?php
      function testAbs_正の値の場合() {
        $expected = 1;
        // テスト対象functionの呼び出し
        $actual = abs(1);
        $this->verify();
      }
      
      function testAbs_負の値の場合() {
        $expected = 2;
        // テスト対象funcitonの呼び出し
        $actual = abs(-2);
        $this->verify();
      }
      
      
    • 悪い例
    <?php
    function testAbs() {
      $expected[0] = 1;
      $actual[0] = abs(1);
    
      $expected[1] = 2;
      $actual[1] = -2;
    
      $this->verify();
    }
    

    「悪い例」の書き方の場合、ケースの中身を確認しないと
    ・何種類のテストを行っているのかが把握できない
    ・どんな観点でテストを行っているのかが把握できない
    といった問題点があります。
    1funciton1条件の前提を守った上で、なるべく条件分岐を網羅するようにテストを作成していきます。

    6. テストfunctionの命名規則

    テストfunctionの名称は、テストの内容を分かりやすくするため

    test【function名】_【条件】_【期待する結果】()
    

    という形式で統一します。命名規則を統一することで可読性が上がり、
    テストコードを書いた本人でなくてもJenkinsのテストレポートを見るとどのようなテストが行われているかが一目でわかります。
    また、条件・期待する結果は日本語で記載することでさらに分かりやすくすることができます。

    testAction_必須項目が入力されていない場合_エラー画面に遷移する()
    

    7. テストクラスの分け方

    テストクラスはテスト対象のfunction毎に1つずつ分けて作成します。
    ただし、後述する「定数による条件分岐」をテストする場合には条件毎にクラスを分ける必要があるためさらに細分化されます。

    8.テストクラスの命名規則

    上で述べたとおり基本的にテストクラスはテスト対象のfunctionに対応するため、

    【対象クラス】_【対象function】Test.php
    

    という名称にします。さらに条件毎にファイルを分ける場合には、

    【対象クラス】_【対象function】_【条件】Test.php
    

    とします。

    • LC_Page_Products_Detail_ActionTest.php
      LC_Page_Products_Detail_Action_HasErrorTest.php
      

    条件によってファイル名を分ける場合には、ファイル名は日本語を避けて定義するようにしてください。

    9. より網羅的にテストを書く方法

    1. 定数による条件分岐

    defineを使って定義されている定数は、テスト中に自由に上書きすることができません。
    そこで、定数の値によって条件が分岐する場合は定数の値ごとにテストコードのファイルを分割します。

    • ソースコード
      <?php
      function sfGetHashString($str, $salt) {
        $res = '';
        if ($salt == '') {
          $salt = AUTH_MAGIC;
        }
        if (AUTH_TYPE == 'PLAIN') {
          $res = $str;
        } else {
          $res = hash_hmac(PASSWORD_HASH_ALGOS, $str . ':' . AUTH_MAGIC, $salt);
        }
        return $res;
      }
      
    • テストコード
      <?php
      $HOME = realpath(dirname(__FILE__)) . "/../../../..";
      // このテスト専用の定数の設定。必ずCommon_TestCase.phpより先に定義する
      define('AUTH_TYPE', 'PLAIN');
      require_once($HOME, "/tests/class/Common_TestCase.php");
      
      // クラス名に条件(authTypePlain)も含める
      class SC_Utils_sfGetHasString_authTypePlainTest extends Common_TestCase {
      
        // AUTH_TYPE=PLAINであることを想定した実際のテストコード
      }
      

    このようにCommon_TestCaseより先に指定したい定数を定義することで、このテストクラスに限定した値を定義することができます。

    2. exitする箇所のテスト

    PHPUnitでテストを行う際には実際にphpのプログラムを走らせることになりますが、
    プログラム中にexitする箇所があるとそこでPHPUnit自体も終了してしまうため、有効なテスト結果を得ることができません。
    EC-CUBEの場合は、pages以下のクラスでSC_Response_Ex::sendRedirect()やSC_Response_Ex::actionExit()を呼んでいる箇所がそれにあたります。
    このような部分をきちんとテストするために、テスト実施時はSC_Response_Exの実装を切り替えてexitしないようにします。
    実装を切り替えた後のクラスはtests/class/replace以下に存在します。
    このクラスをCommon_TestCaseから呼び出すことにより、テスト時の実装を切り替えます。

    <?php
     /**
       * actionExit()呼び出しを書き換えてexit()させない例です。
       */
      public function testExit() {
        $resp = new SC_Response_Ex();
        $resp->actionExit();
    
        $this->expected = TRUE;
        $this->actual = $resp->isExited();   // exit()したかどうかをチェックします。
        $this->verify('exitしたかどうか');
      }
    

    10. テストを書きやすくする対策

    1. functionを「単体」でテストする

    functionの中でさらにfunctionが呼ばれている場合、いちばん外側のfunctionをそのまま実行すると中の分岐が多すぎてテストしきれない場合があります。
    そのような場合は、内側のfunctionの実装をモックに切り替えて欲しい値を自由に返すようにし、外側のfunctionだけをテストするようにします。

    • ソースコード
      <?php
      class Sample {
      function hoge() {
        if (fuga()) {
          return 1;
        } else {
          return 2;
        }
      }
      
      function fuga() {
         return rand() % 2 == 0;
      }
      }
      
    • テストコード
      <?php
      class SampleTest extends PHPUnit_Framcework_TestCase {
        function testHoge_fugaがtrueの場合() {
          $sample = new Sample_Mock();
          $sample->fuga_val = TRUE;
          $this->assertEquals(1, $sample->hoge());
        }
      }
      
      class Sample_Mock extends Sample {
        $fuga_val;
      
        function fuga() {
          return $fuga_val;
        }
      }
      

    この例はそれほど分岐が複雑ではありませんが、内側の関数fuga()の返り値がランダムなのでテストで要求する値を返却させるためにオーバーライドしています。

    2. ユーティリティクラスを使ってデータ準備を効率化する

    テストで常に同じ結果を得られるようにするには、テスト実行のたびにDBの内容を期待値に合わせてリセットする必要があります。
    そのため、EC-CUBEのユーティリティであるSC_Queryクラスを使ってsetUp()の中でデータの準備を行い、tearDown()でロールバックを行います。

    <?php
    class SampleTest extends PHPUnit_Framework_TestCase {
      // データ準備
      protected function setUp() {
        $this->objQuery = SC_Query_Ex::getSingletonInstance();
        $this->objQuery->begin();
        $this->setUpCustomer();  // 実際にデータを投入する箇所
      }
    
      // ロールバック
      protected function tearDown() {
        $this->objQuery->rollback();
      }
    
      // データの定義
      protected function setUpCustomer() {
            $arrValue['customer_id'] = $this->customer_id;
            $arrValue['name01'] = $this->name01;
            $arrValue['name02'] = $this->name02;
            $arrValue['kana01'] = $this->name01;
            $arrValue['email'] = 'test@example.com';
            $arrValue['secret_key'] = 'aaaaaa';
            $arrValue['status'] = 2; // 会員
            $arrValue['create_date'] = 'CURRENT_TIMESTAMP';
            $arrValue['update_date'] = 'CURRENT_TIMESTAMP';
            $this->objQuery->insert('dtb_customer', $arrValue);
      }
    }
    

    よく使うデータ定義はtests/class/util以下のユーティリティクラスから取得できるようにしておき、データの再利用性を高めます。

    3. ユーティリティクラスを使って端末の種類を設定する

    端末の種類がPC・モバイル・スマートフォンのいずれになっているかによって条件が分岐する場合は、
    テスト専用のユーティリティを使用して擬似的に端末の種別を設定します。ユーティリティはtests/class/test/util/User_Utils.phpに定義されています。

    <?php
    /**
       * 端末種別をテストケースから自由に設定する例です。
       */
      public function testDeviceType() {
        $this->expected = array(DEVICE_TYPE_MOBILE, DEVICE_TYPE_SMARTPHONE);
        $this->actual = array();
    
        // 端末種別を設定
        User_Utils::setDeviceType(DEVICE_TYPE_MOBILE);
        $this->actual[0] = SC_Display_Ex::detectDevice();
        User_Utils::setDeviceType(DEVICE_TYPE_SMARTPHONE);
        $this->actual[1] = SC_Display_Ex::detectDevice();
    
        $this->verify('端末種別');
      }
    

    4. ユーティリティクラスを使ってログイン状態を設定する

    ユーザがログインしているかどうかによって処理が分岐する場合は、セッションの情報とDBの値を書き換えることによりテストで要求する分岐を実現します。
    情報を書き換えるfunctionは、端末種別設定と同じくtests/class/test/util/User_Utils.php内で定義されています。

    <?php
      /**
       * ログイン状態をテストケースから自由に切り替える例です。
       */
      public function testLoginState() {
        $this->expected = array(FALSE, TRUE);
        $this->actual = array();
    
        $objCustomer = new SC_Customer_Ex();
        // ログインしていない状態に設定
        User_Utils::setLoginState(FALSE);
        $this->actual[0] = $objCustomer->isLoginSuccess();
        // ログインしている状態に設定
        User_Utils::setLoginState(TRUE, null, $this->objQuery);
        $this->actual[1] = $objCustomer->isLoginSuccess();
    
        $this->verify('ログイン状態');
      }


    Facebook Comment 

  • Q: [EC-CUBE 2系] リファクタリングガイドライン TheVOS 2019.09.28
    A:

    init 関数

    init 関数は, クラスの初期化を目的する. ビジネスロジックの記述はしないこと

    <?php
    function init() {
    
        /**
         * NG ビジネスロジックの記述はしない
         */
        if (count($this->arrPayment) > 0) {
            $i = 0;
            foreach ($this->arrPayment as $val) {
                $this->payment[$i] = $val;
                $i++;
            }
        }
    
        /**
         * OK クラスの初期化のみ行う
         */
        $this->tpl_mainpage = 'index.tpl';
        $this->arrDISP = $masterData->getMasterData('mtb_disp');
    }
    

    action 関数

    action 関数は MVC のコントローラにあたり以下の処理を記述する.

    • 条件分岐
    • VIEW からの入力
    • VIEW に渡すメンバ変数($this->variable_name)への代入
    • 宣言
    • ビジネスロジックの呼び出し

    action 関数に, ビジネスロジックを直接記述したり, SQL を実行する処理を記述しないこと.

    <?php
    /**
     * action 関数のサンプル
     */
    function action() {
    
        /** OK VIEW からの入力を処理する */
        $this->arrForm = $this->lfConvertParam($_POST);
    
        /** OK 入力に応じて条件分岐する */
        switch ($this->getMode()) {
        case 'edit':
    
            /** OK エラーの内容に応じて条件分岐する */
            $this->arrErr = $this->lfProductClassError($this->arrForm);
            if (empty($this->arrErr)){
                $this->tpl_mainpage = 'products/product_class_confirm.tpl';
                $this->lfProductConfirmPage($this->arrForm);
            } else {
                $this->doPreEdit($this->arrForm, false ,true);
            }
            break;
    
        case 'delete':
            $this->doDelete($this->arrForm);
            break;
    
        case 'disp':
            /** NG ビジネスロジックの記述をしてはならない */
            foreach ($this->arrForm as $key => $val) {
                $foo[$key] = $val;
            }
    
            /** NG SQLを実行する処理を記述してはならない */
            $objQuery = SC_Query::getSingletonInstance();
            $arrResults = $objQuery->select('*', 'table_name');
    
            $this->doDisp($this->arrForm);
            break;
    
        case 'complete':
            $this->registerProductClass($this->arrForm, $this->arrForm['product_id']);
            SC_Response_Ex::sendRedirect('complete.php');
            break;
    
        default:
        }
    }
    

    MODE パラメータ

    $_POST['mode'] や $_GET['mode'] に対する条件分岐は, LC_Page::getMode() を使用し, switch 文で記述する.

    <?php
    /** OK switch 文で mode の分岐を行う */
    switch ($this->getMode()) {
    case 'disp':
        $this->doDisp($this->arrForm);
        break;
    
    case 'complete':
        SC_Response_Ex::sendRedirect('complete.php');
        break;
    default:
    }
    
    /** NG mode の条件分岐に if 文を使用してはならない */
    if ($_POST['mode'] == 'disp') {
        $this->doDisp($this->arrForm);
    } elseif ($_POST['mode'] == 'complete') {
        SC_Response_Ex::sendRedirect('complete.php');
    }
    

    ビジネスロジック

    • ページ間で重複する処理が存在する場合は, Helper などの共通クラスへ記述する
    • ページ固有の処理は, ローカル関数で記述する
    • 可能であれば, PHPUnit を使用してテストケースを残すこと
    • 宣言を除き, 引数や返り値が無く, すべて内部のメンバ変数で処理するような関数は極力作成しない
      • ステートレスな処理を心掛けること
    <?php
    
    /**
     * NG 引数ではなく, クラスのメンバ変数を使用して振舞いを変更する
     */
    function lfSendMail() {
         $objPurchase = new SC_Purchase_Ex();
         $objPurchase->sendOrderMail($this->order_id)
    }
    
    /**
     * OK 引数で振舞いを変更できる
     */
    function lfSendMail($order_id) {
         $objPurchase = new SC_Purchase_Ex();
         $objPurchase->sendOrderMail($order_id)
    }
    
    /**
     * NG 引数や返り値が無く, メンバ変数の値を直接変更している
     */
    function lfConvertLoginPass(){
        if(strlen($this->arrForm['login_pass']) < 1 ) {
            return;
        }
        $this->arrForm['login_pass'] = trim($this->arrForm['login_pass']);
        $this->arrForm['login_pass1'] = $this->arrForm['login_pass'];
        $this->arrForm['login_pass2'] = $this->arrForm['login_pass'];
    }
    
    /**
     * OK ローカル関数内では, ローカル変数を使用することで, 拡張性, 保守性が向上し, ユニットテストも書きやすい
     */
    
    $this->arrForm = $this->lfConvertLoginPass($this->arrForm);
    
    function lfConvertLoginPass(&$arrForm){
        if(strlen($arrForm['login_pass']) < 1 ) {
            return;
        }
        $arrForm['login_pass'] = trim($arrForm['login_pass']);
        $arrForm['login_pass1'] = $arrForm['login_pass'];
        $arrForm['login_pass2'] = $arrForm['login_pass'];
        return $arrForm;
    }
    
    /**
     * ユニットテストの例.
     */
    function testLfConvertLoginPass() {
        $login_pass = 'login_pass_value';
        $arrForm = array('login_pass' => $login_pass);
    
        $expected = array('login_pass' => $login_pass,
                          'login_pass1' => $login_pass,
                          'login_pass2' => $login_pass);
    
        $actual = lfConvertLoginPass($arrForm);
    
        $this->assertEquals($expected, $actual);
    }
    
    • ループ処理などで, メンバ変数や, スーパーグローバル変数は直接使わない
    <?php
    
    /**
     * NG ループ処理で, メンバ変数やスーパーグローバル変数を直接扱っている
     */
    foreach ($_POST['params'] as $key => $val) {
         $this->arrForm[$key] = $val;
    }
    
    /**
     * OK メンバ変数や, スーパーグローバル変数に作用するループ処理は, 別途関数を作成する
     */
    $this->arrParams = $this->getParams($_POST['params']);
    
    function getParams($arrParams) {
         $arrResults = array();
         foreach ($arrParams as $key => $val) {
             $arrResults[$key] = $val;
         }
         return $arrResults;
    }
    

    データベースアクセス

    特に理由の無い場合は SC_Query::getSingletonInstance() を使用してインスタンスを取得すること

    <?php
    
    /**
     * NG PHP4 環境では, 新たなインスタンスが生成されてしまう
     */
    $objQuery = new SC_Query();
    
    /**
     * OK シングルトンが保証され, トランザクションの扱いが容易になる
     */
    $objQuery = SC_Query::getSingletonInstance();
    

    SQL 文を散乱させない. SELECT id, name, foo, bar FROM table_name と SELECT id, name, foo, bar, too FROM table_name が存在する場合は, 後者を共通関数にリファクタリングすること

    <?php
    
    /**
     * NG 類似した SQL を散乱させてはいけない
     */
    $arrResults = $objQuery->select('id, name, foo, bar', 'table_name');
    $arrResult2 = $objQuery->select('id, name, foo, bar, too', 'table_name', 'too = ?', $arrParams['too']);
    
    /**
     * OK カラム名や, WHERE の違いなどは共通関数で吸収する
     */
    function getResults($arrParams = array()) {
        $where = '';
        $arrValues = array();
        if (isset($arrParams['too'])) {
            $where .= 'too = ?';
            $arrValues[] = $arrParams['too'];
    
        }
        $objQuery = SC_Query::getSingletonInstance();
        $arrResults = $objQuery->select('*', 'table_name', $where, $arrValues);
        return $arrResults;
    }
    $arrResults = getResults();
    $arrResults2 = getResults($arrParams);
    

    INSERT/UPDATE/DELETE は, SC_Query::insert(), SC_Query::update(), SC_Query::delete() を使用し, SC_Query::query() は使用しないこと

    <?php
    
    /** NG SC_Query::query() は使用しない */
    $objQuery = SC_Query::getSingletonInstance();
    $objQuery->query('INSERT INTO table_name (col1, col2) VALUES (?, ?)', arrary($col1, $col2));
    
    /** OK SC_Query::insert(), SC_Query::update(),  SC_Query::delete() を使用する */
    $objQuery = SC_Query::getSingletonInstance();
    $objQuery->insert('table_name', array('col1' => $col1,
                                          'col2' => $col2));
    

    LIMIT, OFFSET は SC_Query::setLimit(), SC_Query::setLimitOffset() を使用すること.

    <?php
    
    /** NG LIMIT, OFFSET を直接使用しない */
    $objQuery = SC_Query::getSingletonInstance();
    $arrResults = $objQuery->getAll('SELECT * FROM table_name WHERE del_flg = 0 LIMIT 10 OFFSET 5');
    
    /** OK SC_Query::setLimit(), SC_Query::setLimitOffset() を使用する */
    $objQuery = SC_Query::getSingletonInstance();
    $objQuery->setLimitOffset(10, 5);
    $arrResults = $objQuery->select('*', 'table_name', 'del_flg = ?', array('0'));
    

    RDBMS の可搬性向上のため USING 句は使用しないこと

    <?php
    
    /** NG USING 句は使用しない */
    $objQuery = SC_Query::getSingletonInstance();
    $arrResults = $objQuery->select('T1.*', 'table_name T1 JOIN table2_name T2 USING(col)');
    
    /** OK ON 句 を使用する */
    $objQuery = SC_Query::getSingletonInstance();
    $arrResults = $objQuery->select('T1.*', 'table_name T1 JOIN table2_name T2 ON T1.col = T2.col');
    

    入力チェック

    入力チェック用のクラスには, SC_FromParam と SC_CheckError が存在するが, 極力 SC_FormParam を使用すること

    端末種別の判別

    Net_UserAgent_Mobile::isMobile() や MOBILE_SITE 定数など存在するが, SC_Display_Ex::detectDevice() に統一する

    スーパーグローバル変数

    $_POST や $_GET の値は, 必ず入力チェック後に使用する. SC_FormParam を使用していれば, SC_FormParam::getHashArray() で取得できる

    <?php
    
    /** NG $_POST の値を入力チェックせずに使用する */
    $this->register($_POST);
    
    /** OK 必ず入力チェックを行う */
    $objFormParam = new SC_FormParam();
    $objFormParam->addParam('商品規格ID', 'product_class_id', INT_LEN, 'n', array('EXIST_CHECK', 'MAX_LENGTH_CHECK', 'NUM_CHECK'));
    $objFormParam->setParam($_POST);
    $objFormParam->convParam();
    $arrErr = $objFormParam->checkError()
    if (SC_Utils_Ex::isBlank($arrErr)) {
         // 入力チェック後の値が取得可能
         $arrForm = $objFormParam->getHashArray();
    }
    $this->register($arrForm);
    

    $_SESSION は, SC_CartSession クラス等, セッションを扱うビジネスロジックを通じて使用するのが望ましい.

    どうしても, グローバル変数を使用したい場合は, global キーワードは使用せず, $GLOBALS を使用すること.

    <?php
    /**
     * NG global キーワードの使用すると, 変数名衝突の原因となる
     */
    function globalSample() {
        global $conn;
    
        // 外部からは $conn という変数を使用しているのがわからない
        if (is_null($conn)) {
            $conn = new ClassName();
        }
    }
    
    /**
     * OK $GLOBALS を使用すると, ローカル変数との衝突の心配は無い
     */
    function globalSample() {
        if (is_null($GLOBALS['_conn'])) {
            $GLOBALS['_conn'] = new ClassName();
        }
    }
    

    変数名

    変数名で, どんなデータか識別できるよう考慮すること

    <?php
    
    /**
     * NG 一見して, どんなデータが格納されているかわからない
     */
    $arrRet = getProducts();
    
    /**
     * OK 商品データの配列だと, 変数名で判別可能
     */
    $arrProducts = getProducts();
    

    リテラルを格納する (つまり配列・オブジェクト以外の) 変数名は, すべて小文字を使用し, アンダーバーで区切ること

    <?php
    
    /**
     * リテラルを格納する変数名は, 連想配列の添字で使用されることも考慮し
     * アンダーバー区切りの方が扱いやすい
     */
    
    /**
     * NG
     */
    $productId = getProductId();
    
    /**
     * OK
     */
    $product_id = getProductId();
    

    1行の文字数/行数

    • 1行の文字数は80文字までにすることを目指すこと. すなわち, コードの長さを現実的な範囲で80文字までにおさめるよう努力すべきです. しかしながら, 場合によっては少々長くなってしまってもかまいません.
    • 1関数の行数は多くても200行程度に留めるのが望ましい. これ以上行数が増えてしまう場合は, 関数を分割する等, コーディングの見直しを行ってください

    PHPDoc コメント

    関数の PHPDoc コメントは必ず記述する.

    • 関数の説明
    • 引数
      • 引数の無い関数は省略可能
    • 返り値
      • 返り値が無くても void を明記すること

    非推奨機能

    error_reporting(E_ALL) で, エラー及び警告が出力されないようコーディングすること.

    PHP5.3 で非推奨となっている関数は使用しないこと.

    • call_user_method() (かわりに call_user_func() を使用します)
    • call_user_method_array() (かわりに call_user_func_array() を使用します)
    • define_syslog_variables()
    • dl()
    • ereg() (かわりに preg_match() を使用します)
    • ereg_replace() (かわりに preg_replace() を使用します)
    • eregi() (かわりに preg_match() で 'i' 修正子を使用します)
    • eregi_replace() (かわりに preg_replace() で 'i' 修正子を使用します)
    • set_magic_quotes_runtime() およびそのエイリアスである magic_quotes_runtime()
    • session_register() (かわりにスーパーグローバル $_SESSION を使用します)
    • session_unregister() (かわりにスーパーグローバル $_SESSION を使用します)
    • session_is_registered() (かわりにスーパーグローバル $_SESSION を使用します)
    • set_socket_blocking() (かわりに stream_set_blocking() を使用します)
    • split() (かわりに preg_split() を使用します)
    • spliti() (かわりに preg_split() で 'i' 修正子を使用します)
    • sql_regcase()
    • is_dst を mktime() に渡すこと。 かわりにタイムゾーン処理用の新しい関数を使用します。

    以下の機能も, PHP5.3.x で非推奨となっているが, PHP4互換のために使用しても良い EC-CUBE 2.12.0 から PHP4 は非対応となりました.

    • new の返り値を参照で代入すること
    • 呼び出し時の参照渡し

    参考 http://www.php.net/manual/ja/migration53.deprecated.php

    URL のファイルパス部の取得は $_SERVER['PHP_SELF'] を使わず、代わりに $_SERVER['SCRIPT_NAME'] を使用する。(参考: #1717)

    Facebook Comment 

  • Q: [EC-CUBE 2系] EC-CUBE標準規約 TheVOS 2019.09.28
    A:

    基本的に Zend Framework PHP 標準コーディング規約 に順ずる.
    以下, 要点及び相違点を規定する.

    また, コーディングに際して, 以下のガイドラインに沿うことが望ましい

    EC-CUBE標準規約 > リファクタリングガイドライン

    PHPUnitを利用した単体テストを行う際は以下のガイドラインに沿う事が望ましい

    EC-CUBE標準規約 > 単体テストガイドライン

    命名規約

    ファイル名

    • 拡張子は, 各ファイル形式に準ずる.
      • PHPファイルは, 必ず .php を使用する.
    • PHPクラスは, 特別な場合を除き, 1クラス1ファイルとし, クラス名.php とする.

    PHPクラス名

    • 区切り文字としてはアンダースコア(_)を使用する.
    • クラス名称の先頭には, 大文字でその種類を表す Prefix を付加する.
      Prefix 種類
      SC, GC 1つのサイト内で共有するクラス (他のクラスから呼ばれる) SC_Customer.php
      LC 1つのソースファイル内で使用するクラス (通常他のクラスから呼ばれない) LC_Page_Abouts.php
    • クラスがパッケージに属する場合は, Prefix の後にパッケージ名を付加する.
      • Page パッケージでインデックスページとしてアクセスされるクラス名は Index とせず, 属する階層名をクラス名とする.
    • ユーザーが拡張するために extends するクラスは, クラス名の最後に Ex を付加する.

    関数名

    • 関数名の先頭には, 小文字でその種類を表す Prefix を付加する.
      • クラス名: LC_*
        • private または protected を意図する場合、Prefix「lf」を省略できる。(Prefix の付加がない場合、「lf」相当とみなす。)
        • public を意図する場合、Prefix「sf」を省略できない。
      • クラス名: SC_*, GC_*
        • public を意図するメソッドの場合、Prefix「sf」を省略できる。(Prefix の付加がない場合、「sf」相当とみなす。)
        • private または protected を意図する場合、Prefix「lf」を省略できない。
    • 名称が複数の単語からなる場合, それぞれの単語の先頭を大文字にする.
    • 関数名は, Prefix + 動詞 + 対象 を原則とする.
      Prefix 種類
      sf 一つのサイト内で共有する関数 sfGetProductName()
      lf 一つのソースファイル内で使用する関数 lfGetProductName()
      fn JavaScript で宣言された関数 fnGetProductName()

    変数名(Smarty 変数も含む)

    • 変数名の先頭には, 小文字でその種類を表す Prefix を付加する.
      • ループ等で一時的に使用する, 数値型の変数には慣習的な $i, $j, $k を使用しても良い.
    • リテラルを格納する (つまり配列・オブジェクト以外の) 変数名は, すべて小文字を使用し, アンダーバーで区切る.
    • 配列・オブジェクトの変数名はキャメルケースを使用する.
      Prefix 種類
      obj クラス変数(オブジェクト) $objQuery
      arr 配列 $arrCustmers
      tpl テンプレート変数(リテラル) $this->tpl_csv_id

    定数名

    • すべて大文字で宣言する.
    • 区切り文字としてアンダースコア(_)を使用する.
    • パスに関わるもの(パラメータを含む)は、下記を適用する。(#834 から展開)
      • *_URL: URL
        • 先頭は「スキーム名:」
      • *_URLPATH: URL における url-path 相当 (絶対パス)
        • 先頭は「/」
      • *_HTMLPATH: URL 上の EC-CUBE の /html/ からの相対パス
        • 先頭に「/」を含まない。(/html/ と同一の場合、空文字)
        • 命名に改善余地あり。 (参考: concrete5=DIR_REL) 現在は利用箇所が無いが、今後利用する必要も考えられるので再考していきたい。
      • *_REALFILE: (サーバの)ファイルシステム上のファイルの絶対パス
        • 先頭は「/」
      • *_REALDIR: (サーバの)ファイルシステム上のディレクトリの絶対パス
        • 先頭は「/」。末尾は「/」。
      • *_DIR: 上記に該当しない断片的なディレクトリ情報。
        • 先頭に「/」を含まない。
      • *_FILE: 上記に該当しない断片的なファイル情報。
      • *_PATH: 上記に該当しないもの。上記の複数に該当するもの。

    DBテーブル名

    • テーブル名の先頭には, 小文字でその種類を表す Prefix を付加する.
    • 区切り文字としてアンダースコア(_)を使用する.
    • Prefix 種類
      mtb マスタデータ mtb_pref
      dtb データテーブル dtb_order_detail

    DBカラム名

    • 特に指定の無い限り, すべて小文字を使用する.
    • 区切り文字としてアンダースコア(_)を使用する.

    CSS クラス名

    • 特に定義なし

    コーディング規約

    HTML

    • ラジオボタン, チェックボックスは <label></label> で囲み, 文字をクリックしてもチェックされるようにする.

    PHPコード

    • 改行コードは, 基本的に LF を使用する.
      • 使用する Subversion クライアントによっては, svn add を実行した際に, OS 元来の改行コードがリポジトリに反映されてしまう場合があるため, svn propset で svn:eol-style=LF を設定しておくのが望ましい.
    • PHPコードの開始タグと, 終了タグは以下のように記述する.
    • 終了タグの後に必ず LF (UNIX の改行コード)を1つ入れる.
    • 余分な空行, 行末の空白は極力削除する.
    • クラス定義, 関数定義の後, 括弧の後で改行する.
    • 80 文字を目安に改行する.
      <?php
      class LC_Page_Abouts
      {
      
          function process()
          {
              // some logic.
          }
      }
      

    制御文

    • if, for, while, switch 等の制御構造は, 次のルールで開き括弧で記述する.
    • インデントは, 半角スペース4文字を使用し, タブは使用しない.
    • if 文
      <?php
      if ($flag == '1') { // '1' == $flag と書くのは NG
          $ret = 1;
      } elseif ($flag == '2') {
          $ret = 2;
      } else {
          $ret = 3;
      }
      
      • 判定文の対象となる処理結果は先に記述する.
    • for 文
      <?php
      for ($i = 0; $i < $max; $i++) {
          echo $i . "\n";
      }
      
    • foreach 文
      <?php
      foreach ($var as $key => $val) {
          echo $key . ':' . $val . "\n";
      }
      
    • while 文
      <?php
      while ($flag) {
          var_dump($flag);
      }
      
    • do while 文
      <?php
      do {
          var_dump($flag);
      } while ($flag);
      
    • switch 文
      <?php
      switch ($var) {
          case VAR_ONE:
              echo 'one';
              break;
      
          case VAR_TWO:
              echo 'two';
              break;
      
          default:
              echo 'default';
              break;
      }
      
      • case の記述は, 定数を用いるのが望ましい.

    文字列

    • 長くなる文字列は分割し, "." で結合する.
      <?php
      $sql = 'SELECT name, age, birthday, zipcode, address, comment '
           . '  FROM user_information '
           . ' WHERE user_id = ? '
           . '   AND is_delete = 0 ';
      
    • ヒアドキュメントを使用しても良い
      <?php
      $sql = <<< __EOS__
          SELECT name,
                 age,
                 birthday,
                 zipcode,
                 address,
                 comment
            FROM user_information
           WHERE user_id = ?
             AND is_delete = 0
      __EOS__;
      

    SQL文

    • フォームから入力された値を利用して SQL文を生成する場合, SQLインジェクションを防ぐため, 必ず PEAR::MDB2 のブレースホルダを利用する.

    コメント

    • コメントのコーディングは基本的に phpDocumentor に準ずる.

    ヘッダ

    • 各ファイルのヘッダに著作権表記を記述する.
      <?php
      /*
       * This file is part of EC-CUBE
       *
       * Copyright(c) 2000-2011 LOCKON CO.,LTD. All Rights Reserved.
       *
       * http://www.lockon.co.jp/
       *
       * This program is free software; you can redistribute it and/or
       * modify it under the terms of the GNU General Public License
       * as published by the Free Software Foundation; either version 2
       * of the License, or (at your option) any later version.
       *
       * This program is distributed in the hope that it will be useful,
       * but WITHOUT ANY WARRANTY; without even the implied warranty of
       * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       * GNU General Public License for more details.
       *
       * You should have received a copy of the GNU General Public License
       * along with this program; if not, write to the Free Software
       * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
       */
      

    クラス定義

    • phpDoc コメントは必要に応じて記述する.
    • @version は $Id$ を使用する.
    • メンバ変数は / */ を使用することによって phpDoc コメントとして認識される.
      <?php
      /**
       * クラスの簡単な説明
       *
       * クラスの詳細な説明....
       * ...
       *
       * @package Page
       * @author LOCKON CO.,LTD.
       * @version $Id$
       */
      class LC_Page
      {
      
          /** メンバ変数 */
          var foo;
      
      }
      

    Pageクラス

    • class/pages以下において exit; を個別の処理でしない。exit処理はすべてSC_Response_Ex::actionExit(); に共通化すること.

    関数定義

    • phpDoc コメントは必要に応じて記述する.
      • @param と @return は必須
    • コード文中にも必要に応じて的確なコメントを記述する.
      <?php
      /**
       * 関数の簡単な説明.
       *
       * 関数の詳細な説明....
       * ....
       *
       * @access private
       * @param string $foo 引数の説明
       * @param string|integer $bar 引数の説明
       * @return string 返り値の説明
       */
      function process($foo, $bar = '')
      {
          // some process...
          return 'string value';    
      }
      

    その他

    • 必要に応じて, 下記のタスクタグを使用しても良い
      • TODO - TODO として残したいコメント
      • FIXME - 必ず修正することを促すコメント
      • XXX - 動くけど怪しい...
        <?php
        // TODO リファクタリングすること.
        
        // FIXME 要修正. バグの説明(#135)
        
        /**
         * :XXX: 以下, 怪しいロジック(#999)
         * 複数行のコメントはこのように.
         *
         * 必要に応じて チケットの ID も記述する.
         */
        
    • コメントによってソースコードが見難くならないように注意する.

    Facebook Comment 

Board Pagination Prev 1 2 Next
/ 2