2011/08/17

viの操作練習用のテキスト

CentOSにはviエディタの操作練習用のコマンドがありますので紹介します。
30分くらいで一通りの操作を紹介してくれるテキストです。viに慣れていない人は、ぜひ一度見てみると参考になります。
終了するときは、viと同じ「[esc] :q」です。

なお、表示は日本語なので安心してください。

$ vimtutor

2011/08/11

symfonyコマンドでエラーになる人に

symfonyのコマンドを入力するときは、当然ですがプロジェクトの直下でないとエラーになります。
$ pwd
/home/user/proj/web
$ symfony cc

  [Exception]
  you must be in a symfony project directory

まあ、プロジェクトのディレクトリに移動して打ち直せはいいのですが。
$ cd ~/proj
$ symfony cc
>> file+     /home/user/proj/front_dev-cli.lck
>> chmod 777 /home/user/proj/front_dev-cli.lck
>> file-     /home/user/proj/front_dev-cli.lck
>> file+     /home/user/proj/front_prod-cli.lck
>> chmod 777 /home/user/proj/front_prod-cli.lck
>> file-     /home/user/proj/front_prod-cli.lck

変数CDPATHを使うと少しだけ横着できます。
$ export CDPATH="/home/user"
$ echo $CDPATH
/home/user
$ cd proj
/home/user/proj
「export CDPATH="/home/user"」は、.bash_profileに記述しておけば、ログインのたびに毎回打ちなおす必要はありません。

また、プロジェクトに限らず、よく使うディレクトリを変数CDPATHにいれておけば、cdでディレクトリ移動のときタイプする文字数が少なく出来ます。


2011/08/10

Mysqlのテーブル内容確認方法、その2(open office)

Mysqlのテーブル内容確認をopen officeで出来たのでその方法です。

eclipseからMySQLへの接続を出来たのですが、画面が狭いので他の方法を探していたところ、open officeで出来ることが判りました。

作業項目
  1. open officeでmysql接続の拡張機能を追加する。
  2. open officeで新しい仮のDBを作成、このDBからmysqlが参照出来ます。

作業手順
(1)open officeでmysql接続の拡張機能を追加する。
(a)MySQL Connectorダウンロード

(b)機能拡張マネージャをツールメニュー/機能拡張マネージャで呼びだし、追加。先ほどダウンロードした「MySQL Connector」を選択。

(c)「MySQL Connector」が追加されました。
ここで一度Open Officeを再起動しないとドライバは認識されないみたいです。

(2)open officeで新しい仮のDBを作成、このDBからmysqlが参照出来ます。
(a)起動画面にて、ファイルメニューから新規作成、データベース


(b)DB選択画面にて、既存のデータベースに接続


(c)接続セットアップにて、直接接続
(JDBCコネクタを使えばJDBCコネクタでも接続できます)


(d)MySQLサーバデータセットアップにて、データベース名とサーバ名を入力。
サーバ名はxampp環境ならlocalhostです。
(e)ユーザ認証セットアップにて、ユーザ名入力、テスト接続


(f)テスト接続にて、パスワード入力


(g)接続確認画面が表示されたら、OKで戻る。


(h)再びユーザ認証セットアップ、次へ

(i)保存続行で、完了
ここで、「いいえ、データベースへ登録しません」を選択してもofficeのDBは作成されます。

(j)DBの保存画面
次回このDBを起動すると、mysqlに接続されます。


(k)MySQLのデータベースが表示されます。



ちなみに、excelでもアクセス出来るのだろうか?

<参考>
058-MySQL 5.1 OpenOffice 3.2 Base 直接接続

2011/08/05

telnetでのlsのカラー表示を止めたい

symfonyのディレクトリで属性をapacheがアクセスできるようにしていると、lsコマンドでカラー表示したとき、属性によってはディレクトリやファイル名の文字が読みにくいことがあります。

オプションの指定でカラー表示しないことが出来ます。
$ ls --color=none

毎回コマンドを入力したくなければ環境変数LS_COLORSを取り消すことでも同じ効果が得られます。
一時的な対応なら、telnetでログインしたあと、再度bashなどシェルを立ち上げそこでクリアすれば、しばらくカラーなしで使えます。
$ unset LS_COLORS

2011/07/15

eclipseからapacheのログを見る

symfonyで作業していて、CentOS上のプロジェクトを操作していて、symfonyのメッセージでは判らないエラーがでたとき、apacheのエラーログを確認したいときがあります。
telnetでapacheのログを見れれば特に問題ありません。

apacheのログは、デフォルトでは以下にあります。
/var/log/httpd

eclipseで見れたら便利です。eclipseでリモートシステムエクスプローラでもフォルダまでは参照可能です。しかしファイルは一般ユーザでは見れません。
一般ユーザで参照可能にするためには、権限を追加します。
(rootユーザで作業して下さい)

# chmod +rx /var/log/httpd

確認、「.」にrxがあればOK
# ls -la /var/log/httpd
drwxr-xr-x 2 root root 4096 7月 14 19:30 .
...

apacheのログは大きくなるので、eclipseで見るときはフリーズしやすいです。
メモリの少ないPCでは、telnetでアクセスしてlessやtailコマンドで見るようにしましょう。

2011/07/11

viエディタのコマンド

symfonyを使っていると、プロジェクト内ならeclipseで照会編集できますが、symfonyプロジェクト以外でファイルを編集することがあります。
そんなときは、viのお世話になります。linuxに慣れているならともかく、phpの開発環境としてlinuxを使っているとき、viは使いにくいものです。少しでも使いやすいように、覚えておくと便利なコマンドを紹介します。

最初はやはりこれです。
・カーソル移動
h 左
j 下
k 上
l 右

慣れてきたら、以下のコマンドをお勧めします。
・移動を早くするためのコマンド
w,W 順方向移動(単語単位)
b,B 逆方向移動(単語単位)
小文字の場合、「,」などの句読点なども区切りに含まれる。
好みによりますが、大文字の方が良いかもしれません。しかしshiftキーを押す手間がかかります。
カーソル移動の際、矢印キーよりキーストロークを少なく出来ます。

・テキスト移動
^ 行の先頭へ
$ 行の最後へ

・行の入力
o カーソルの下に1行追加
O カーソルの上に1行追加

・削除
d^ 行の先頭から削除
d$ 行の最後まで削除

・vi起動時のカーソル位置指定
vi +10 tmp.txt
10行目を指定して起動
vi +/ccc tmp.txt
cccを検索して起動

これくらい覚えておくと作業効率が上がったように感じます。

2011/07/08

symfonyのコマンド補完機能

symfonyでコマンドの補完機能を設定します。
慣れてくると必要ない機能かもしれませんが、初心者のうちはスペルミスでコマンドが動かないことを回避するなど無駄な時間の節約になります。

symfonyで使用するユーザのhomeディレクトリに「~/.bash-completion」で以下のファイルを作成。(symfony 1.0.20で確認)
_symfony()
{            
  local cur prev action
  COMREPLY=()   
  cur=${COMP_WORDS[COMP_CWORD]}
  prev=${COMP_WORDS[COMP_CWORD-1]}
  action=${COMP_WORDS[1]}
  
  case "$prev" in
    init-module|propel-generate-crud|propel-init-crud|propel-init-admin|propel-load-data|propel-build-all-load)
      COMPREPLY=( $( compgen -W "$( ls --color=n -1 apps 2>/dev/null| sed -e 's/ /\\ /g' )" -- $cur ))
      return 0
    ;;
    init-project)
      COMPREPLY=( $( compgen -W "$( basename $PWD )" -- $cur ))
      return 0
    ;;
    init-app)
      COMPREPLY=( $( compgen -W "frontend backend" -- $cur))
      return 0
    ;;    
    symfony)
      COMPREPLY=( $( compgen -W "$( symfony -T | awk '/^  /' | cut -d' ' -f3 )" -- $cur ) )
      return 0
    ;;    
    plugin-install)
    COMPREPLY=( $( compgen -W 'local global' -- $cur ) )
    return 0
    ;;
    global|local)
    COMPREPLY=( $( compgen -W 'symfony/' ) )
    return 0
    ;; 

    *)
      case "$action" in
        propel-generate-crud|propel-init-crud|propel-init-admin)
          if (($COMP_CWORD == 3)); then
            COMPREPLY=( $( compgen -W "$( find lib/model -maxdepth 1 -name '*.php' -exec basename {} .php \; |grep -v Peer\$| tr [:upper:] [:lower:] )" -- $cur ) )
          elif (($COMP_CWORD == 4)); then
            COMPREPLY=( $( compgen -W "$( find lib/model -maxdepth 1 -name '*.php' -exec basename {} .php \; |grep -v Peer\$ )" -- $cur ) )
            
          fi
          return 0
          ;;
      esac
      return 0
    ;;
      sync)
          if (($COMP_CWORD == 3)); then
            COMPREPLY=( $( compgen -W 'go' -- $cur))
          fi
          return 0
          ;;
    esac

    return 0  
}
       
complete -F _symfony symfony

symfony 1.1はこちら
_symfony()
{            
  local cur prev action
  COMPREPLY=()
  cur=${COMP_WORDS[COMP_CWORD]}
  prev=${COMP_WORDS[COMP_CWORD-1]}
  action=${COMP_WORDS[1]}

  case "$prev" in
    "init-module"|"propel-generate-crud"|"propel-init-crud"|"propel-init-admin"|"generate:module"|"propel:generate-crud"|"propel:init-admin")
      COMPREPLY=( $( compgen -W "$( ls -1 apps 2>/dev/null | sed -e 's/ /\\ /g' | sed -e 's/\/$//g' )" -- $cur ) )

      return 0
    ;;

    "init-project"|"generate:project")
      COMPREPLY=( $( compgen -W "$( pwd | perl -pe "s/^.*?([^\/]+)$/\$1/g" )" -- $cur ) )

      return 0
    ;;

    "init-app"|"generate:app")
      COMPREPLY=( $( compgen -W "frontend backend" -- $cur ) )

      return 0
    ;;    

    "sync")
      if (($COMP_CWORD == 3)); then
        COMPREPLY=( $( compgen -W 'go' -- $cur))
      fi

      return 0
    ;;

    *symfony)
      SYMFONY_VERSION=$( $prev -V | sed 's/^symfony version //g' | awk -F '.' '{print $1 "." $2;}' )

      case "$SYMFONY_VERSION" in
        0.*)
          # Versions less than 1.0 are not supported.
          COMPREPLY=()
        ;;

        "1.0")
          COMPREPLY=( $( compgen -W "$( $prev -T | awk '/^  /' | cut -d ' ' -f 3 )" -- $cur ) )
        ;;

        *)
          COMPREPLY=( $( compgen -W "$( 
NAMESPACE=''
OLD_IFS=$IFS

IFS=$'\n'
for line in $( $prev -T ); do
  if [ $line != 'Available tasks:' ]; then
    if [ ${line:0:2} == '  ' ]; then
      TASK=$(echo $line | awk -F ':' '{print $2;}' | cut -d ' ' -f 1)
      if [ -z $NAMESPACE ]; then
        echo $TASK
      else
        echo $NAMESPACE:$TASK
      fi
    else
      NAMESPACE=$line
    fi
  fi
done

IFS=$OLD_IFS
)" -- $cur ) )

          # Work-around bash_completion issue where bash interprets a colon as a separator.
          # Work-around borrowed from the darcs work-around for the same issue.
          local colonprefixes=${cur%"${cur##*:}"}
          local i=${#COMPREPLY[*]}
          while [ $((--i)) -ge 0 ]; do
            COMPREPLY[$i]=${COMPREPLY[$i]#"$colonprefixes"} 
          done
        ;;
      esac

      return 0
    ;;    

    *)
      case "$action" in
        "propel-generate-crud"|"propel-init-crud"|"propel-init-admin"|"propel:generate-crud"|"propel:init-admin")
          if (($COMP_CWORD == 3)); then
            COMPREPLY=( $( compgen -W "$( find lib/model -maxdepth 1 -name '*.php' -exec basename '{}' '.php' ';' | grep -v 'Peer$' | tr [:upper:] [:lower:] )" -- $cur ) )
          elif (($COMP_CWORD == 4)); then
            COMPREPLY=( $( compgen -W "$( find lib/model -maxdepth 1 -name '*.php' -exec basename '{}' '.php' ';' | grep -v 'Peer$' )" -- $cur ) )
          fi

          return 0
        ;;
      esac

      return 0
    ;;
  esac

  return 0  
}

complete -F _symfony symfony

さらに、.bashrcファイルに追記。
[ -f ~/.bash-completion ] && source ~/.bash-completion


設定を反映
$ source ~/.bashrc


これで、symfonyコマンドの補完機能が使えるようになります。
(補完機能を使うとき、候補が複数のあるときは、tabキーを2回押して下さい)
$ symfony  (ここでtabキーを押します)
app                        plugin-uninstall
batch                      plugin-upgrade
cc                         propel-build-all
clear-cache                propel-build-all-load
clear-controllers          propel-build-db
controller                 propel-build-model
disable                    propel-build-schema
downgrade                  propel-build-sql
enable                     propel-convert-xml-schema
fix-perms                  propel-convert-yml-schema
freeze                     propel-dump-data
init-app                   propel-generate-crud
init-batch                 propel-init-admin
init-controller            propel-init-crud
init-module                propel-insert-sql
init-project               propel-load-data
log-purge                  sync
log-rotate                 test-all
module                     test-functional
new                        test-unit
plugin-install             unfreeze
plugin-list                upgrade

また、コマンドの途中では
$ symfony init- (ここでtabキーを押します)
init-app         init-controller  init-project
init-batch       init-module

などの使い方があります。

 <参考>
BashCompletion
symfonyコマンドを補完する
 自動補完

2011/07/02

vmwareのCentOSにあるsymfony projectに外部のPCからアクセスする

vmwareのCentOSにあるsymfony projectに外部のPCからアクセスする。
vmware上のCentOSにあるsymfonyで開発しているプロジェクトの内容をローカルPC以外でも確認したいことがあります。SVNを使っていれば反映するだけですが、それほどでもないときは、外部PCから確認できれば便利です。

vmwareのネットワーク設定で、nat接続とbridge接続の説明は、以下の資料を参照して下さい。
<参照資料>
VMware FusionにおけるNat接続とBridge接続


vmwareが起動されているPC以外のPCからvmware上のサーバにアクセスするためには、以下の方法があります。
(1)Nat接続でport forward設定をする
(2)Bridge接続にする

今回は、(2)Bridge接続で設定してみました。
<事前確認>
・vmwareのネットワーク設定確認
VMware Playerで、メニューから仮想マシン/仮想マシンの設定...
ネットワークアダプタ、ネットワーク接続



・ここで、ブリッジになっていれば、外部PCから接続できます。
NATになっている場合は、Bridge接続に変更することによって外部PCから接続できるようになります。



<設定変更作業>
(1)vmwareのネットワーク設定変更
(2)CentOS上でネットワーク再設定
(3)外部PCのhostsファイル設定


(1)vmwareのネットワーク設定変更
ネットワーク接続で、ブリッジを選択、物理ネットワーク接続もチェックを入れる



(2)vmware上CentOSにてネットワーク設定
  ネットワーク設定の変更作業なので、telnetなどは使えません。
  vmware playerの画面で直接作業する必要があります。
まず、rootでログインしてネットワークの状態を確認
# ifconfig
これで、eth0の表示のあるものが、ネットワークアダプタの状態です。
ネットワークを一度落とします。
# ifconfig eth0 down
ここにIPアドレスを設定します。
ここで設定するIPアドレスは、vmwareの乗っているPCのIPアドレスと同じネットワークにする必要があります。
つまりPCが192.168.2.3だった場合、192.168.2.xになります。
# ifconfig eth0 192.168.2.8 netmask 255.255.255.0 broadcast 192.168.2.255
  設定結果の確認
# ifconfig eth0 up
# ifconfig

<確認>
・外部PCから、DOSコマンドでvmwareのCentOSに対して接続確認
> ping 192.168.2.8
これで、pingが戻ればネットワーク接続は変更されています。

(3)外部PCのhostsファイル設定
C:\Windows\System32\drivers\etc\hosts
192.168.2.8   www.sfproject.com
hostsファイルを保存したら、再度DOSコマンドにてpingで確認
> ping www.sfproject.com
次に、Webの画面からアクセスできることを確認します。

 <恒久的な対応>
ifconfigの設定は、linuxを再起動すると消えてしまいます。
このため、再起動しても保存されるようネットワーク設定ファイルの変更をします。
/etc/sysconfig/network-scripts/ifcfg-eth0ファイルの設定
DEVICE=eth0
BOOTPROTO=statuc
BROADCAST=192.168.2.255
IPADDR=192.168.2.8
NETMASK=255.255.255.0
NETWORK=192.168.2.0
HWADDR=00:00:00:00:00:00
ONBOOT=yes
設定したら、linuxを再起動して、アクセス確認します。


<参考>
【 固定IPアドレスを設定する 】

2011/07/01

symfonyで関数定義されているコード(ファイル)を検索

symfonyに慣れていると、クラスやメソッド、関数定義が何処にあるかだいたい判るようになるみたいです。しかし、初心者は定義を探すのに苦労します。
symfonyの定義が、linuxのコマンドでとりあえずファイルまで分かります。
あとはソースコードをひたすら眺めることになるのですが。
(windowsのxampp環境だとファイル検索が使えるので何も問題ない)

・コマンドの例、symfonyのパスは自分の環境に合わせて下さい。
$ find /usr/share/pear/symfony/ | xargs grep "function-id"
symfonyのパスになければ、プロジェクトにあるかもしれません。

・コードの例、アクション
public function executeForm()
{
    $this->temp_value = $this->getRequestParameter('temp_value');
    return sfView::SUCCESS;
}

・コードの例、テンプレート
<?php echo $temp_value?>
<?php echo form_tag("default/form" ,"method=post") ?>
<?php echo input_tag("temp_value", "", array('maxlength' => 10)) ?>
<?php echo submit_tag("入力する") ?></div>
</form>

・ここで「getRequestParameter」を探すと、
$ find /usr/share/pear/symfony/ | xargs grep "getRequestParameter"
/usr/share/pear/symfony/generator/sfCrudGenerator.class.php:      $params[] = "\$this->getRequestParameter('".sfInflector::underscore($pk->getPhpName())."')";
/usr/share/pear/symfony/generator/sfCrudGenerator.class.php:      $test_pks[] = sprintf("!\$this->getRequestParameter(%s)", $fieldNameAsArgument ? "\$$fieldName" : "'".$fieldName."'");
/usr/share/pear/symfony/generator/sfCrudGenerator.class.php:      $retrieve_params[] = "\$this->getRequestParameter(\$$fieldName)";
/usr/share/pear/symfony/action/sfComponent.class.php:  public function getRequestParameter($name, $default = null)

ファイル:/usr/share/pear/symfony/action/sfComponent.class.php
定義:public function getRequestParameter($name, $default = null)

・「form_tag」を探すと、
$ find /usr/share/pear/symfony/ | xargs grep "form_tag"
/usr/share/pear/symfony/helper/FormHelper.php: *   <code><?php echo form_tag('@m  yroute'); ?></code>
/usr/share/pear/symfony/helper/FormHelper.php: *   <code><?php echo form_tag('/m  odule/action', array('name' => 'myformname', 'multipart' => true)); ?></code>
/usr/share/pear/symfony/helper/FormHelper.php:function form_tag($url_for_options   = '', $options = array())
/usr/share/pear/symfony/helper/FormHelper.php: * plan to upload files to your we  bsite, be sure to set the <i>multipart</i> option form_tag helper function to tr  ue
/usr/share/pear/symfony/helper/FormHelper.php: * @see input_tag, form_tag
/usr/share/pear/symfony/helper/JavascriptHelper.php:   * The hash passed as a se  cond argument is equivalent to the options (2nd) argument in the form_tag() help  er.
/usr/share/pear/symfony/helper/UrlHelper.php:    return form_tag($internal_uri,   array('method' => 'post', 'class' => 'button_to')).content_tag('div', tag('input  ', $html_options)).'</form>';

ファイル:/usr/share/pear/symfony/helper/FormHelper.php
定義:function form_tag($url_for_options   = '', $options = array())


<参照>
いまさらxargsの便利さを主張してみる

2011/06/24

eclipseでxampp環境のapacheのログを確認する

pleiades環境を使ってphpの開発環境を使っている場合、インストールのフォルダ構成にもよりますが、apacheのログは以下のパスで確認出来ます。
P:\pleiades\xampp\apache\logs\error.log

エクスプローラでapacheログのフォルダを開いておけば、テキストエディタで、access.logやerror.logを確認出来ます。

さらに、eclipseからも確認出来ます。
ウインドウメニューから設定
設定画面で、Ntail/定義ビュー
新規ボタンで、以下の設定
Log view name : ここは判り易いID
Log file name : P:\pleiades\xampp\apache\logs\access.log
これで設定されます。
参照は、eclipseの左下のアイコン(ビューを高速ビューとして表示する)で、その他を選択
ビューの表示で、ロギング/NTailを選択
linuxのtailコマンドと同様にファイルの最後が表示されます。

まあ、エクスプローラでテキストエディタを起動できるので、わざわざeclipseから見たいということはあまりありませんが、eclipseからも参照出来るということです。
eclipseで表示したときのメリットとしては、エディタでも出来ますが、フィルタの設定でしょうか。

linux環境だとeclipseのNtailは使えませんが以下の方法があります。
root権限でコマンド実行(sudoの設定)

むりやりやるならsambaの導入でしょうか。

2011/06/21

symfonyでデバックメッセージ

symfonyでデバックしているとき、echoでデバック情報を出力しています。
しかし、処理の途中でechoを入れると画面が壊れたりして、何をデバックしているのかわからなくなるときがあります。

そんなときは、デバック情報をログに出力する方法があります。
これだと、設定をそのままにして、開発中に後からでも参照することが出来ます。
なお、levelはemerg、alert、crit、err、warning、notice、infoとdebugです。

アクションでは
$level = "debug";
$message = "log message test";
$this->logMessage($message, $level);

テンプレートでは
<?php use_helper('Debug') ?>
<?php $level = "debug";?>
<?php $message = "log message test(template)";?>
<?php log_message($message, $level) ?>

結果は、/proj/log/app_dev.logに書き出されます。
May 01 23:19:19 symfony [debug] log message test
May 01 23:19:19 symfony [debug] log message test(template)

参照URL
ログメッセージを追加する

2011/06/08

php講習が終了しました。

6月7日(昨日)で、基金訓練が終了しました。

これからブログの内容を整理しようと考えております。
タイトル、内容の修正、追加作業をしております。
内容に矛盾があることも考えられますのでご了承ください。

2011/06/04

eclipseリモートシステムのsshターミナル表示が止まる、入力が受け付けない。

symfonyを使っていると、linux環境にターミナル接続(telnet)で作業することがあります。
普段は、puttyやteratermのお世話になっていますが、軽い修正だけのときは、eclipseだけで作業することもあります。
こんなとき、symfony ccなどが必要になると、eclipseのssh接続を使います。
しかし、ときどきssh接続のターミナルが固まってしまうことがありました。
仕方がないのでターミナルの切断と再接続をしていました。
でも、以下の対応で復活することがあります。

ctrl-sを押してしまった。
ctrl-qで復活。

考えてみると、eclipseでソースを保存しようとしてctrl-sを押すことは良くあります。
ソースを保存しようとしていたのですが、そのときアクティブになっていたターミナルの表示を止めていただけのようです。


参照URL
特別のキーストローク

2011/06/01

symfonyの環境でjavascript

5/30の作業

・授業もあと1週間です。
・symfonyの環境でjavascriptの練習
Webのテキスト(おまけ/Javascript基礎)を参照

・javascriptを書くところはhtml(symfonyではテンプレートファイル)
scriptタグに書く

<準備>
一般ユーザにて作業
・symfonyのプロジェクトjavascriptを作る。
$ mkdir javascript
$ cd javascript/
$ symfony init-proj javascript
・アプリケーションはfront
$ symfony init-app  front
・モジュールはdefault
$ symfony init-module front default
・apacheのvhost設定(ここはrootユーザ)
# vi /etc/httpd/conf/httpd.conf
<VirtualHost *:80>
    DocumentRoot /home/user/javascript/web
    ServerName www.javascript.local
    ErrorLog logs/www.js.local-error_log
    CustomLog logs/www.js.local-access_log common
    alias  /sf /usr/share/pear/data/symfony/web/sf
    <Directory "/home/user/javascript/web">
      Allowoverride All
      Options -Includes -ExecCGI
    </Directory>
</VirtualHost>
・設定後は、apacheの再起動
# /etc/rc.d/init.d/httpd restart
ロ-カルのhostsファイル変更も忘れずに

・アクションとテンプレートの修正

・「javascript練習」の文字をブラウザで表示出来ることを確認する

<内容>
(1)javascriptでアラート表示
・テンプレートにjavascriptを記述
<script type="text/javascript">
alert("Hello Fujisawa");
</script>

・実行して、アラートが表示されることを確認する。

(2)javascriptのコードを外部へ
・テンプレートの修正
<script type="text/javascript" src="/js/main.js">
</script>

・外部ファイル作成
/web/js/main.jsファイルを作成し、内容を記述。
alert("Hello Fujisawa");
(SEO対策として、CSS同様javascriptも外部ファイルにすることを推奨されているらしい)

・実行して(1)と同様アラートが表示されることを確認する。


(3)javascriptの記述場所による違い
(A)aタグ(アンカータグ)への埋め込み
・テンプレートの修正
<a href="javascript:alert('Hello');">ポップアップ</a>
・ポップアップをクリックしてアラートが表示されることを確認

(B)「イベントハンドラ」としてスクリプトを埋め込む
・テンプレートの修正
<input type="button" value="クリック" onclick="btnOnClick()">
・javascriptは関数として(layout.phpの)headタグに
<script type="text/javascript">
function btnOnClick() {
    alert("クリックされました");
}
</script>
・クリックボタンを押してアラートが表示されることを確認

・javascriptは致命的なエラー以外、軽いものはエラーがわかりずらい。
Firebugのコンソールにjavascriptのエラーが表示されるので、動きがおかしいときはここのメッセージを確認する。

<その他のイベント
・on + イベント名
<body onload="alert('load');">
(これはlayout.phpのbodyタグ)
・Webのリフレッシュでアラート表示

・selectタグを使って、変更されたときのイベント
テンプレートの変更
<select id="pref" name='pref' onchange="checkPref(this.value);">
<option value='1'>北海道</option>
<option value='2'>青森</option>
</select>

・関数
(前記の例ではheadタグに関数を置いたが、javascriptの関数記述は呼び出された後でも良い)
<script type="text/javascript">
function checkPref(pref) {
    if (pref == 1) {
        alert("北海道が選択されました");
    } else if (pref == 2) {
        alert("青森が選択されました");
    }
}
</script>
・selectを切り替えてアラートが表示されるのを確認

<javascriptの使われ方>
・Webの画面で、項目入力中にバリデーションをかけ、右側にエラーを表示。
・しかし、入力中のエラーチェックは、ブラウザ側でjavascriptを無効にすると、
動かないので、最終的にはサーバ側(php,perl)でチェックする。

<変数>
・varを付ける。

<ループ>
・ループ(文字の連結は+)
<script type="text/javascript">
for (var i=0; i < 10; i++) {
      document.writeln("iの値は" + i + "<br>");
    }
</script>
・表示を確認

<配列>
<script type="text/javascript">
var ary = ['鈴木', '佐藤', '田中'];
for(var i = 0; i < ary.length; i++) {
      document.writeln(ary[i] + "<br>");
}
</script>
・表示を確認
・javascriptでは、オブジェクトの関数呼び出しは「.」でつなぐ。

・関数の練習:三角形の面積を求める関数を作る
<script type="text/javascript">
document.writeln('三角形の面積(5,2):' + triangle(5,2));

function triangle( base, height) {
    return base * height /2 ;
}
</script>
・表示を確認

<関数リテラル>
javascriptは、関数を引数として使うことが出来る。
関数リテラルは、実行時に評価されるため、呼び出し元のコードよりも先に
記述する必要がある。
・ここは大切、復習しておいて
・関数リテラルを使う目的は部品化。
<script type="text/javascript">
 triangle = function(base, height) {
      return base * height / 2;
    }

document.writeln('三角形の面積は' + triangle(5, 2));
</script>


<スコープ>
(1)変数がスクリプト全体から参照できるグローバルスコープ
(2)その変数が定義された関数の中でのみ参照できるローカルスコープ

(1)関数内でvarの記述がない場合、グローバルスコープ
<script type="text/javascript">
scope = 'グローバル';
function getValue() {
  scope = 'ローカル';
  return scope;
}
document.writeln(getValue() + "<br>");
document.writeln(scope + "<br>");
</script>

(2)関数内でvarを付けるとローカルスコープ
<script type="text/javascript">
var scope = 'グローバル';
function getValue() {
  var scope = 'ローカル';
  return scope;
}
document.writeln(getValue() + "<br>");
document.writeln(scope + "<br>");
</script>
・結果を表示して違いを確認する。


<DOM>
DOM(Document Object Model)とは、HTMLやXMLで書かれたドキュメントに
アクセスするための標準的な仕組み。

属性 widthなど
要素 pタグなど
テキスト 

・サンプル、ID値をキーにノードを取得する
<script type="text/javascript">
function btn_click() {
    var result = document.getElementById("result");
    result.innerHTML = "こんにちは" + document.fm.name.value + 'さん';
}
</script>

<form name="fm">
<input type="text" name="nname" id="name">
<input type="submit" value="送信" onclick="btn_click(); return false;">
<div id="result"></div>
</form>
・表示されるinputタグに名前を入れて、名前が表示されることを確認する。

・サンプル、その2、pタグのタグ名をキーにノードを取得し、アラート表示
<p>Hello!</p>
<p>Good night!</p>

<script type="text/javascript">
function btn_click() {
    var result = [] ;
    var list   = document.getElementsByTagName('p');
    for ( var i=0; i <list.length; i ++) {
        result.push(list.item(i).innerHTML);
    }
    alert(result.join(","));
}
</script>

<form name="fm">
<input type="submit" value="確認" onclick="btn_click(); return false;">
</form>
・確認ボタンを押すと、pタグのテキストがアラートに表示されるのを確認する。

・相対的な位置関係でノードを取得する
<script type="text/javascript">
window.onload = function() {
    var result = [] ;
    var food   = document.getElementById("food");
    var options = food, childNodes;

    for (var i=0; i<options.length; i++) {
        var option = options.item(i);
        if (option.nodeType ==1) {
            result.push(options.item(i).value);
        }
    }
    alert(result.join(','));
}
</script>

<select name="food" id="food">
<option value="ラーメン">ラーメン</option>
<option value="餃子">餃子</option>
<option value="シュウマイ">シュウマイ</option>
</select>
・画面のリフレッシュで、selectタグのテキストがアラートに表示されるのを確認する。
・「window.onload」は読み込んだときに関数が実行される。


<javascriptのフレームワーク:jquery
・テキストとしてダウンロードして、symfonyプロジェクトのディレクトリ/web/js/jquery.jsで保存
・jqueryを使うと記述が簡単になる。
・documentationのGetting Started から読んで
・ドキュメントの日本語版は古い場合があるので英語で読む

・layout.phpのheadタグで読み込むように修正
<script type="text/javascript" src="/js/jquery.js"></script>

・jquery、サンプル
<h1>javascript練習</h1>
<script type="text/javascript">
alert($("h1").html()) ;
</script>
・h1タグのテキストが、アラートのメッセージに表示されることを確認する。

2011/05/23

SVN (Subversion)インストール

5/23の内容

・今日は、昨日と違って寒い。
・今日の授業は、久々に課題以外の話題。
開発の現場にてソースの管理に利用されているSubversion( サブバージョン) の
環境設定と使い方について。

(1)SVNのインストールと環境設定

(2)windowsからSVNを参照するためのソフトTortoiseSVNをインストール

(3)SVNを使って開発環境から本番環境へソースを移行するための
擬似環境を設定。

(4)擬似環境を使って、変更の手順をシミュレーション

(5)最後の1時間は、環境をクリアして、本日の作業を再度実行。


以下詳細手順、Webテキスト参照。(2,4,5は別に記述する予定)

(1)SVNのインストールと環境設定
(A)CentOSサーバにsvnをインストール
rootユーザにて作業(コマンドの先頭に#があるものはrootユーザにて実行)
# yum -y install subversion mod_dav_svn
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * addons: centos.tt.co.kr
 * base: centos.tt.co.kr
 * extras: centos.tt.co.kr
 * updates: centos.tt.co.kr
addons                                                   |  951 B     00:00
base                                                     | 1.1 kB     00:00
extras                                                   | 2.1 kB     00:00
updates                                                  | 1.9 kB     00:00
utterramblings                                           |  951 B     00:00
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package mod_dav_svn.i386 0:1.6.11-7.el5_6.3 set to be updated
---> Package subversion.i386 0:1.6.11-7.el5_6.3 set to be updated
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package            Arch        Version                    Repository      Size
================================================================================
Installing:
 mod_dav_svn        i386        1.6.11-7.el5_6.3           updates         78 k
Updating:
 subversion         i386        1.6.11-7.el5_6.3           updates        3.1 M

Transaction Summary
================================================================================
Install       1 Package(s)
Upgrade       1 Package(s)

Total download size: 3.2 M
Downloading Packages:
(1/2): mod_dav_svn-1.6.11-7.el5_6.3.i386.rpm             |  78 kB     00:00
(2/2): subversion-1.6.11-7.el5_6.3.i386.rpm              | 3.1 MB     00:05
--------------------------------------------------------------------------------
Total                                           525 kB/s | 3.2 MB     00:06
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
  Updating       : subversion                                               1/3
  Installing     : mod_dav_svn                                              2/3
  Cleanup        : subversion                                               3/3

Installed:
  mod_dav_svn.i386 0:1.6.11-7.el5_6.3

Updated:
  subversion.i386 0:1.6.11-7.el5_6.3

Complete!


(B)リポジトリの作成
リポジトリは、ソースを管理するための書庫のことです。
今回は、/var/www/svn/shonanbbsにリポジトリを作成します。
# cd /var/www/svn
(svnディレクトリがなければ作る)
・リポジトリ作成
# svnadmin create shonanbbs
・ディレクトリ所有者の変更
# chown -R apache:apache shonanbbs

(C)設定ファイル(svnserve.conf)修正、その1
# cd /var/www/svn/shonanbbs/conf
# vi svnserve.conf
・設定ファイル(svnserve.conf)は以下のように修正
[general]
anon-access = none
auth-access = write
password-db = passwd

(D)設定ファイル(svnserve.conf)修正、その2
svnを使用するユーザの設定
# vi /var/www/svn/shonanbbs/conf/passwd
・設定内容を追加
[users]
ユーザー名1 = パスワード1

(E)svnを使用するユーザに環境変数を追加
SVNを使用するとき、使用するエディタ(vi)をユーザの環境変数に設定する。
一般ユーザにて(コマンドの先頭に$があるものは一般ユーザにて実行)自分のhomeディレクトリに移動
$ cd ~
$ pwd
/home/user
$ ls -la
...(途中省略)
-rw-r--r--  1 user user  199  5月 23 22:14 .bash_profile
...(このあとも省略)
$ vi .bash_profile
・ファイルの最後に追加(svnを使用するエディタの指定)
export SVN_EDITOR="vi"
・設定を有効化
$ source .bash_profile
・有効化を確認
$ env
...(途中省略)
SVN_EDITOR=vi
...(このあとも省略)

(F)SVNサーバをrootユーザで起動
# svnserve -d -r /var/www/svn
・プロセスが起動されたか確認
# ps -ef | grep svn
root     14662     1  0 11:44 ?        00:00:00 svnserve -d -r /var/www/svn
root     14664 14633  0 11:44 pts/0    00:00:00 grep svn
svnサーバの起動を一般ユーザでも出来るみたいだけど、
今回はrootユーザにて起動する。

(G)リポジトリの内容を作成するため、まずCentOS上のlinuxのIPアドレスを確認する。
(rootユーザでも一般ユーザに戻って作業してもいい)
$ /sbin/ifconfig
eth0      Link encap:Ethernet  HWaddr 00:0C:29:03:CE:E1
          inet addr:192.168.47.128  Bcast:192.168.47.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe03:cee1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          ... (以下省略)
・IPアドレスは、「192.168.47.128」

これから、リポジトリの内容を設定
・本番環境側 trunk
・開発環境側 branches

(H)trunk作成
(ここからは一般ユーザで作業)
$ svn mkdir svn://192.168.47.128/shonanbbs/trunk
viが立ち上がるので、コメントはcreate ripositoryを入力
create ripository

-- この行以下は無視されます --

A    svn://192.168.47.128/shonanbbs/trunk

・保存したあと、認証を求められることがあります。先ほど(D)で設定した
パスワードを入力
認証領域: <svn://192.168.47.128:3690> 99a5f541-...
'user' のパスワード:


(I)trunkにソースの情報をインポート(あくまでも管理情報をインポートするだけ?)
今回は「/home/user/bbs2」が管理対象ディレクトリ。
$ svn import /home/user/bbs2 svn://192.168.47.128/shonanbbs/trunk
コメントは、import bbs2を入力、テキストを保存するとインポートが始まり、「追加しています」のメッセージが表示されます。
> リビジョン 2 をコミットしました。
インポート対象(管理対象)に日本語のファイル名を使っているとインポートできないとのこと。

(J)tagsを作成(リリース後のバージョンを保存しておく場所)
$ svn mkdir svn://192.168.47.128/shonanbbs/tags
コメントは、create tagsを入力
> リビジョン 3 をコミットしました。

(K)trunkをbranchesにコピー(本番環境から開発環境にSVNの情報をコピー)
$ svn cp svn://192.168.47.128/shonanbbs/trunk svn://192.168.47.128/shonanbbs/branches
コメントは、create branches
> リビジョン 4 をコミットしました。


(3)SVNを使って開発環境から本番環境へソースを移行するための
擬似環境を設定。

(L)ディレクトリを準備
このディレクトリに、php(symfony)のソースコードが入ります。
・開発環境
$ mkdir /home/user/dev
・staging環境(検証環境?)
$ mkdir /home/user/staging
・本番環境
$ mkdir /home/user/real

(M)apacheの設定ファイルにドメインを割り当てる (この作業はrootユーザで)
# vi /etc/httpd/conf/httpd.conf
・vhostの設定は、それぞれ以下のとおり
www.dev.com         /home/user/dev/web
www.staging.com     /home/user/staging/web
www.rl.com        /home/user/real/web
(ms securityでwww.real.comがセキュリティの警告を受けたので変更しました)
なお、授業と同じ環境にしたければ以下の通り。
dev.shonanbbs.com     /home/user/dev/web
staging.shonanbbs.com /home/user/staging/web
www.shonanbbs.com     /home/user/real/web(本番はbbs2から変更する)

・vhostの内容は以下の通り(staging,realも作成)
<VirtualHost *:80>
    DocumentRoot /home/user/dev/web
    ServerName www.dev.com
    ErrorLog logs/dev.com-error_log
    CustomLog logs/dev.com-access_log common
    Alias /sf "/usr/share/pear/data/symfony/web/sf"
    <Directory "/home/user/dev/web">
      Allowoverride All
      Options -Includes -ExecCGI
    userDirectory>
userVirtualHost>
・apache再起動
# /etc/rc.d/init.d/httpd restart
httpd を停止中:                                            [  OK  ]
httpd を起動中: Warning: DocumentRoot [/home/user/dev/web] does not exist
Warning: DocumentRoot [/home/user/staging/web] does not exist
Warning: DocumentRoot [/home/user/real/web] does not exist
                                                           [  OK  ]
・まだphp(symfony)のソースコードとフォルダの環境を設定していないので、apache上ではワーニングが表示されます。

(N)windowsのhostsファイルも更新する。
・hostsファイルの内容は省略します。
・この時点では、ブラウザからdev、staging、realにアクセスしても、
ソースがないのでエラーが出る。
Not Found

The requested URL / was not found on this server.

(O)ソースコードのチェックアウト(co) (コピー)
$ svn co svn://192.168.47.128/shonanbbs/branches ~/dev
$ svn co svn://192.168.47.128/shonanbbs/trunk ~/staging
$ svn co svn://192.168.47.128/shonanbbs/trunk ~/real

> リビジョン 4 をチェックアウトしました。
これで、各環境にWebでアクセスすれば、bbs2が表示される。

(P)権限設定を各環境で実施
各環境では、symfonyのディレクトリ所有者がuserなので、apacheからアクセスした場合、エラーが出る。
(キャッシュに残っているデータで表示が可能な場合はエラーが出ないかも)
このため、各環境で権限設定を変更する。
$ symfony fix-perms

(Q)svnで管理されているフォルダは「.svn」がある
$ cd ~/dev
$ ls -la
合計 64
drwxrwxr-x 14 user user 4096  5月 23 14:30 .
drwxr-xr-x 19 user user 4096  5月 23 14:15 ..
drwxrwxr-x  6 user user 4096  5月 23 14:30 .svn
drwxrwxr-x  6 user user 4096  5月 23 14:30 apps
以下略
・確認
$ svn info
パス: .
URL: svn://192.168.47.128/shonanbbs/branches
リポジトリのルート: svn://192.168.47.128/shonanbbs
リポジトリ UUID: 64e80751-e84d-4801-8776-33d37fbd49db
リビジョン: 4
ノード種別: ディレクトリ
準備中の処理: 特になし
最終変更者: user
最終変更リビジョン: 4
最終変更日時: 2011-05-23 13:17:17 +0900 (月, 23  5月 2011)

以上、ここまでインストールと環境設定。
さすがに長くなったので、以降は別にします。

2011/05/17

php講習 5/17

・本日は、室内の掃除当番でした。

・昨日に引き続き最終課題の6日目

<本日の作業>
・マンション一覧の項目調整。項目が多い。
設計書と、テーブル定義で項目の並びが揃っていない。
設計書には日本語表記の項目名のみ、テーブル定義のカラム名が入っていない。

・プロジェクトをコピーしたとき、権限でエラーになるときの対処
$ symfony fix-perms
しかし、今日は何故か一部のイメージファイルがないとのエラーになる。
昨日までうまく動いていたのに不思議。
aparcheを再起動したらファイルがないとのエラーが出なくなった。
aparcheが何かを憶えているのか、それとも、タイミングの問題か。

・問い合わせで、物件情報の表示項目が区分により異なる処理を作成。

・問い合わせのパンくずリストで、戻り先を区分で判定。

・マンションの明細を作成。項目が多いので見直しが大変。

・レイアウト調整、見本のWebページを見ながらCSSの指定を作成。
土地明細の問い合わせ先の下部分をテーブルタグからDIVタグに修正。
追加CSSの設定をview.ymlに設定

・見本のイメージファイルは、/imgの指定。しかし、デフォルトのsymfonyでは
  /imagesなので、cssの該当部分を修正

明日はお休み。
木曜日でレイアウト調整が終わるだろうか?

2011/05/12

php講習 5/12

・本日も雨のため、掃除は中止

・最終課題3日目
・明細ページの作成(2日目)
出力項目が多いのと、仕様書とテストデータが合っていない部分がある。
データの検証にも時間がかかる。
・社名の表示は固定項目にした。

・お問い合わせページ作成
入力項目で、タグにする部分の調整に時間がかかる。
内容のバリデーションは、必須項目のみ
詳細はあとで追加予定



・確認画面の調整が終わり、登録のアクションで時間切れ。
ラジオボタンのデータ保存と、表示の処理を残した。
・そのあと、メール送信処理あり。

・細かい設定内容は、あとで追記するかもしれません。

2011/05/11

php講習 5/11

今日は雨で外の掃除はなし。

・最終課題2日目
<環境準備>
・vmware上のCentOSをあげるのに15分かかった。
1分程度で上がるときもあれば、時間がかかるときもある。
違いがわからない。

<土地の一覧表>
・一覧表検索条件ラジオボタンの配列作成
後から気が付いたが、参考にもらったファイルに、setting.ymlファイルがあり、
設定があった。
自分で作らなくてもよかったが、練習なので自分で作るようにとの指導とのこと。
・画像種別1 - 6
1:間取 2:外観 3:地図 4:周辺 5:内装 9:その他画像 10:玄関 11:居間 12:キッチン 13:寝室 14:子供部屋 15:風呂
「土地」には、種別4,6しかなかった。また、種別がセットされていないものもあり。

・検索条件
(1)図面の有無1、外観画像
(2)図面の有無2、区画画像
(3)図面の有無3、外観・区画以外

・ラジオボタンの書き方
    <?php foreach ($gaikan_sitei as $k => $v): ?>
    <?php echo radiobutton_tag("sort", $k, $gaikan_sitei==$k); ?>
    <?php echo $v.' '; ?>
    <?php endforeach; ?>

・検索条件をcriteriaで判断するのに、種別の項目が1-6まであるので
andとorの条件を設定するのに半日かかった。

・午後から土地詳細画面作成
表示項目が多いので時間がかかる。
カラム名が日本語の資料しかないため、DB上のカラム名を探すにに時間がかかる。
その上、データが入っていないものもある。1項目設定するのに10-15分かかる。

・レイアウト調整しながら作成。
今日は、物件番号まで、情報更新日以降は明日。

・ちなみに、情報更新日は、mysql上のdateタイプデフォルト表示と、phpの日付が
異なるため、調整が必要。

2011/05/10

symfony最終課題

php講習  5/10

今日は、認定日のため2時間目からの出席でした。
それにしても、今日は暑かった。

本日から、最終課題。

作業手順は以下の通り。

(1)データベース(realestate)作成
> create database realestate;
作ったら確認
> show databases;

(2)データベースユーザ作成
> GRANT ALL ON realestate.* TO realestate@"localhost" IDENTIFIED BY "xxxx";
> flush privileges;
作ったら確認
> select host,user from mysql.user;

(3)DBのdumpファイルをデータベースにインポート
・Webテキストから落とすとき、エラーが出ないのに、一部しか落ちないときがあった。
6回目でようやくファイルが得られる。79Mありました。
データをインポート
$ mysql -u root realestate <dump.sql
作ったらmysqlで確認
> use realestate;
> show tables;


(4)プロジェクト(realestate)作成
> symfony init-project realestate

(5)ドメイン設定(www.shonan-realestate.com)
<VirtualHost *:80>
    DocumentRoot /home/user/realestate/web
    ServerName www.shonan-realestate.com
    ErrorLog logs/rst.com-error_log
    CustomLog logs/rst.com-access_log common

    alias  /sf /usr/share/pear/data/symfony/web/sf

    <Directory "/home/user/realestate/web">
       AllowOverride All
       Options -Includes -ExecCGI
    </Directory>
</VirtualHost>
・ローカルPCのhostsファイル設定

(6)環境設定
db接続,schema,model,sfPageFlow,task追加など
imgファイルセットアップ
・基本モジュール設定
$ symfony init-app front
$ symfony init-app backend
$ symfony init-module front default
$ symfony init-module backend default
・DB接続環境設定
$ symfony propel-build-schema
$ symfony propel-build-model
$ symfony cc
・ページャは独自のツールなので記述は省略します。

(7)スタート

・本日は、frontで(土地の)一覧表と、検索条件を1項目(価格)作ったところで終了。
同一カラムのand条件検索は、以下のページを参照しました。
同じカラムのAND条件を作る場合
 

・予定では、作業時間2週間だそうです。

2011/05/09

php講習 5/9

本日のメモはあとで更新します。

GW明けなので、先月の復習と、コメント欄のテキストエディタ適用

2011/05/05

root権限でコマンド実行(sudoの設定)

symfonyでときどき、root権限のコマンドを実行する必要に迫られます。
そのたびにrootに切り替えるのも手間なので、sudoコマンドを実行すると簡単です。
そのためには、設定が必要です。

<一般ユーザでsudoを実行できるようにする設定>
一度、rootユーザに切り替えて作業します。

$ su -
# visudo
ここで、パスが通っていなければ、/usr/bin/visudoで試して下さい。

viが起動されるので、以下の記述まで進めて下さい。
## Allows people in group wheel to run all commands
# %wheel        ALL=(ALL)       ALL
この行を有効に
%wheel        ALL=(ALL)       ALL

あとは、viと同様に保存して終了して下さい。

次に、 ユーザの確認
# id  user
uid=501(user) gid=501(user) 所属グループ=501(user)

ユーザにグループwheelを追加
# usermod --groups wheel user

グループが追加されたか確認
# id  user
uid=501(user) gid=501(user) 所属グループ=501(user),10(wheel)

これで、root権限でコマンドが実行できるようになります。
・コマンド
$ sudo tail /var/log/httpd/mysyte.com-error_log

2011/05/04

symfonyでエラーとなったときのapacheログの表示

ローカルで開発環境を作っているとき、symfonyの開発環境で
デバックモードをfalseにしたままで、エラーが出るとデバックモードを
trueに設定しなおして(または、_devで)、再実行しています。

これって面倒なので、apacheのログを見て判る範囲であれば、
エラーが確認出来ます。

(1)rootでapacheのエラーログを確認する。
・apacheのログの指定は、以下の設定ファイルに記述されています。
/etc/httpd/conf/httpd.confにVirtualHostの設定をしています。
>    ErrorLog logs/mysyte.com-error_log
>    CustomLog logs/mysyte.com-access_log common

・「ErrorLog」がエラーログの記述です。
「logs/mysyte.com-error_log」は「/var/log/httpd/mysyte.com-error_log」
のことです。

・ログの最後をrootユーザで確認する。
# tail /var/log/httpd/mysyte.com-error_log


・一般ユーザでは、権限がないので(おそらく)見れません。
どうしても見たければ、rootユーザにて以下のコマンドで権限を変更して下さい。
# chmod +rx /var/log/httpd/

(2)telnetでログインしているときはsymfonyのコマンドを入力するために一般ユーザになっています。このため、上記の権限設定がなければ、毎回rootユーザに切り替えるのも手間がかかります。
決まった作業なので、sudoを使えば一般ユーザでもログを確認出来ます。
ちなみに、sudoについて徹底攻略では、p.303に記述があります。
sudoの設定はこちら)

2011/04/27

php講習 4/27

<午前>
・昨日に引き続き自主課題を使ってsfPageFlowの練習

<午後>
午後のテーマは2つ
(1)掲示板でsfpageflowを使い、お問い合わせフォームを作成
・パラメータの使い方など
フォームでラジオボタン作成
セレクトタグ作成
チェックボックス作成
テキストエリア作成
・これだけでも結構一杯いっぱい。
(2)メールの送信


<午前>
・BBS、front/member_editでニックネームの重複チェック
(カスタムチェックmyNicknameValidator.class.php)
ログイン状態なので、自分のニックネームはあるが、
それ以外と重複しているか、IDで確認。sfpageflowでIDが渡せないトラブル。

<対応>
(1)pageflow.ymlにてパラメータidを受け渡すよう記述追加
 ProcessValidate:
    entry:
     - acceptRequests:
       params:  [id, nickname, mailaddress, password, admin_yn, ]
(2)Initializeアクションにてidをセット
     $this->flow->setData('id', $member->getId());
(3)displayFormテンプレートにてidをパラメータで渡す
<?php echo input_hidden_tag('id', $flow->getData('id')) ?>
(4)カスタムバリデーションにて受け取り、チェック
     if ($member[0]->getId()==$request->getParameter('id')) {
・判ってしまえば、昨日やったことの復習だった。


<午後>
・まず、contentテーブル作成
create文は、メールで送付されています。
もし、contentテーブルが既にある人は、一度テーブルをdropして下さい。
テーブルが出来たら、スキーマ、モデルも作成しておく。
symfony ccも忘れずに。

・お問い合わせ入力フォームの作成
symfony propel-generate-create front contact_add Contact

作成したら、メッセージを日本語にするなど、レイアウト調整。

・昨日の復習、sfpageflowでのパラメータの渡し方の解説
(重要な(混乱しやすい)ことは繰り返し説明してくれるので、ここは重要と認識)

・sfPageFlowでは、データはFlowオブジェクトに持つ。(デジャヴ?)
(Flowオブジェクトを経由して受け渡し)
参照するときは、
アクションは、$this->flow
テンプレートは、$flow
(pageflow.ymlにてパラメータの追加も忘れずに)

・通常のsymfonyのアクションで使う下記の記述は使えない。
sfPageFlowでは、必ずフローオブジェクトを使用する。
$this->name

・チェックボックスの記述は複雑だが、例のとおり書くと覚えておく。
分からない人はプログラムを読んで理解して。
<?php if ($sf_request->haserror('kind')) :?>class="errortd"<?php endif;?>>
<?php echo checkbox_tag('kind[]', 1,in_array(1, $flow->getData('kind'))); ?>資料請求<br>
<?php echo checkbox_tag('kind[]', 2,in_array(2, $flow->getData('kind'))); ?>商品について<br>
<?php echo form_error('kind'); ?>
・チェックボックスデータのDB保存
    $contact->setKind($this->getRequestParameter('kind'));
    kind[]は配列なので、そのままDBには入らないため、文字列にする。
    $contact->setKind(implode(',',$this->getRequestParameter('kind')));
・ちなみにこちらは逆の処理(DBから呼び出すとき?)
explode() - 文字列を文字列により分割する、文字列の配列を返します。

・お問い合わせフォームはメールで送付されているので、詳細はそちらを
確認して下さい。


(2)メール送信処理
・その1:問い合わせデータ保存のタイミングで、メール送信
// $bodyにメール本文
$body = "以下の内容でお問い合わせいただきました。\n\n" ;
$body .= "お名前".$contact->getName();

mb_internal_encoding("utf-8");
mb_language("japanese") ;
mb_send_mail('tmp@localhost',
"subject:test",$message_for_user,$body,
"From:".mb_encode_mimeheader('担当者'). "<tmp@localhost>") ;

・その2:本文を別に作成
・使うための記述
        $this->setFlash('contact', $contact) ;
        $message_for_user =
        $this->getPresentationFor('mail','sendUserAfterContact') ;
・作るための記述
(1)mailモジュール、sendUserAfterContactアクションを作成
(こちらは素のsymfonyです、混乱しないように)
(2)アクション
$this->contact = $this->getFlash('contact') ;
$this->setFlash('contact', null) ;
return sfView::SUCCESS;
(3)テンプレート
お問い合わせありがとうございます。
以下の内容でお問い合わせを承りました。
お名前:<?php echo $contact->getName();?>
<?php $pref = sfConfig::get('sf_pref');?>
都道府県: <?php echo $pref[$contact->getPref()];?>

・メールのあて先は、自分のメールアドレスでテスト。
・残りの時間は(明日も)、自主課題への反映で練習。

2011/04/26

symfonyのsfpageflow

php講習 4/26

<今日の内容>
・フォームを簡単にするためのプラグイン
・symfonyのコマンドに追加する(タスクの追加)
  sfpageflowを使って自動生成する、  今回コマンドの作り方はやらない

<説明>
・sfPageFlowとは
    * フォームのページ遷移をyml で管理し
    * 煩雑なフォーム処理をシンプルに構築できる。
・本日は、sfPageFlowを使って、入力、確認、保存の流れを
  自動生成する機能を実習
・使用するファイルはそれぞれWebテキストからダウンロード可能です。

(1)pluginの設置
/plugins/sfPageFlowPlugin

(2)自動生成タスクの設置
/bbs2/data/tasks/に設置

(3)addonファイルの設置
・設置場所確認
$ whereis pear
pear: /usr/bin/pear /etc/pear.conf /etc/pear /usr/share/pear
/usr/share/pearにsymfonyはある

・ここからは、rootになってaddonファイルを移動後、展開
# mv addon.zip /usr/share/pear/symfony/addon/prople/generator
# unzip addon.zip
Archive:  addon.zip
replace sfPropelCrudGenerator.class.php? [y]es, [n]o, [A]ll, [N]one, [r]ename: y
 inflating: sfPropelCrudGenerator.class.php
 inflating: sfPropelEditGenerator.class.php
 inflating: sfPropelListGenerator.class.php
# ll
合計 24
-rw-r--r-- 1 usr usr 4926  4月 26 10:41 addon.zip
-rw-r--r-- 1 root root 1766  3月 11 14:39 sfPropelAdminGenerator.class.php
-rw-r--r-- 1 root root 3991  7月  2  2009 sfPropelCrudGenerator.class.php
-rw-r--r-- 1 root root 3991  7月  2  2009 sfPropelEditGenerator.class.php
-rw-r--r-- 1 root root 3991  7月  2  2009 sfPropelListGenerator.class.php
# rm addon.zip

(4)スケルトンファイルの設置(generator.zip)
# pwd
/usr/share/pear/data/symfony
# ll
合計 60
drwxr-xr-x 2 root root  4096  3月 11 14:39 bin
drwxr-xr-x 2 root root  4096  3月 11 14:39 config
drwxr-xr-x 2 root root  4096  3月 11 14:39 data
drwxr-xr-x 4 root root  4096  4月 26 11:06 generator
-rw-r--r-- 1 usr usr 13994  4月 26 11:02 generator.zip
drwxr-xr-x 2 root root 12288  3月 11 14:39 i18n
drwxr-xr-x 3 root root  4096  3月 11 14:39 modules
drwxr-xr-x 7 root root  4096  3月 11 14:39 skeleton
drwxr-xr-x 2 root root  4096  3月 11 14:39 tasks
drwxr-xr-x 4 root root  4096  3月 11 14:39 web

・今あるgeneratorは、バックアップし、generator.zipを展開
# mv generator generator_bk
# unzip generator.zip

(5)ヘルパー追加
/lib/helper/下に設置
・このファイルはメールで送付されています。

・これで準備が整いました。

(6)自動生成(symfonyのユーザコマンド)、bbsを使って説明
#CREATE
$ symfony propel-generate-create アプリケーション名  モジュール名  モデル名
$ symfony propel-generate-create front testmember_add Member

#EDIT
$ symfony propel-generate-edit アプリケーション名  モジュール名  モデル名
$ symfony propel-generate-edit front  testmember_edit  Member

#LIST
$ symfony propel-generate-list アプリケーション名  モジュール名  モデル名
$ symfony propel-generate-list front  testmember_list  Member
listはsfpageflowは使っていないとのこと

・新規登録
$ symfony propel-generate-create front testmember_add Member
実行結果にエラーが出なければOK
・確認
http://www.bbs.com/testmember_add/flow
・sfPageFlowのアクションは必ずflow(inputではない)

・一覧表
symfony propel-generate-list front testmember_list Member
実行結果にエラーが出なければOK
・listは、自動生成したものに対して、作業がある。
アクションの関数をmodelに移動
http://www.bbs.com/testmember_list/index

・フロー制御(pageflow.yml)
firstState: ProcessInitialize
lastState:  DisplayResult
state:
  DisplayForm:
    transition:
      doInput:   ProcessValidate
  DisplayConfirm:
    transition:
      doConfirm: ProcessSubmit
      doCancel:  ProcessSetup
  DisplayResult:
  ProcessInitialize:
    transition:
      onSuccess: ProcessSetup
  ProcessValidate:
    entry:
      - acceptRequests:
        params:  [nickname, mailaddress, password, admin_yn, ]
    transition:
      onSuccess: DisplayConfirm
      onError:   DisplayForm
・命名規則
display はテンプレート、process はアクション
transition: 遷移
ProcessValidate:(バリデーション)
entry: 入力値(ここの書いているパラメータがバリデーションに渡る)
逆に記述されていないものは渡らない

・入力、確認、保存をする場合はプログラムを変更しなくていい。
・pageflow.ymlは、自分で追って復習して下さい。

・入力フォームを変更して、メッセージを日本語にする。
<th><span class="required"></span>nickname</th>
 ↓
<th><span class="required"></span>ニックネーム</th>

・入力フォームのパラメータに次の作業(transition:遷移)が指定されている。
DisplayForm.php
<?php echo input_hidden_tag('pageflow_event', 'doInput') ?>
pageflow.yml
  DisplayForm:
    transition:
      doInput:   ProcessValidate

・これまでの処理では、post/sessionでデータを渡していた。
ページフローでは、セッションのフローオブジェクト(flow object)に
パラメータがある。
・このため値の参照方法が今までと変わる。フロー制御では、以下の通り。
アクションでの記述
$this->flow->
テンプレートでの参照
$flow
・これまでの$this->nameでは値は渡らないので注意。
テンプレートに渡すとき
$this->flow->setData('msg', '入力画面です。') ;
アクションで受け取るとき
$member = $this->flow->getData('member');
テンプレートで受け取るとき
$flow->getData('msg')

・アクション、executeValidateでは、パラメータ受け取りの処理がない。
フローオブジェクトが自動的にセットされている。
(あえて言うまでもないかもしれないけど、executeSubmit()でも
パラメータの受け取り処理はない)

・DBのアクセス方法も変わる。(プログラムactions.class.php参照)
confirmで$memberを作成、セッションに持たせておく
resultで$memberを受け取り、保存

・バリデーションは、受け取るアクション.yml
validate.yml
fields:
  nickname:
    required:
      msg: ニックネームを入力してください。

・一覧から編集
$ symfony propel-generate-edit front testmember_edit Member

・画面が出来たら、メッセージを日本語に修正、編集を呼び出せるようにする。
<td><?php echo link_to("編集","testmember_edit/flow?id=".$item->getId());?></td>

・編集
$ symfony propel-generate-list front  testmember_list  Member

・編集完了後、完了画面でF5を押すとエラーになる。
完了でセッションは切れるので、セッション情報はない。
編集画面に必要なidがパラメータで取得できないためエラーになる。
・対応
       $member = MemberPeer::retrieveByPk($this->getRequestParameter('id'));
       if (!$member) {
           $this->redirect('testmember_list/index') ;
       }

・削除は、list処理に含まれているので呼び出す処理を追加。
<td><?php echo link_to("編集","testmember_edit/flow?id=".$item->getId());?> |
 <a onclick="return confirm('削除しますか?');" href="testmember_list/index?delete=on&id=<?php echo $item->getId();?>">削除</a>
</td>

・削除後、F5でエラーになる。URLにIDが残るため、if文を加える。
       if ($this->getRequestParameter('delete') == 'on') {
           $member = MemberPeer::retrieveByPk($this->getRequestParameter('id'));
           if ($member) {
               $member->delete();
           }
       }

・以上の機能を使えば、F5、戻るボタンなどを自分で組まないといけない
ところが自動で組み込まれる。
今後は、sfPageFlowで組んで下さい。

・残りの時間は、自主課題にsfPageFlowを組み込んで練習する。

<環境設定> 
(プロジェクト毎に必要なのは1,2,5、アプリケーションごとに必要なのは6)
(1)pluginの設置
/plugins/sfPageFlowPlugin
(2)自動生成タスクの設置
/data/tasks/myPakePropelEditGenerator.php,他2
(3)addonファイルの設置(共通)
(4)スケルトンファイルの設置(共通)
(5)MyUtilityHelper.phpの設置
(6)templates/_pager.phpの設置(入れ替え、アプリケーションごと、メールで送付されてます)
(共通)部分は、bbsで設定している(はず)なので、既に設定済みのもの

*  sfPageFlowのスケルトンをテンプレートにしている。
何か表示を加えたいときは、スケルトンファイルに加える。
興味のある人は中を見ておいて。

・今週の残りの時間は、自主課題に組み込み練習を積んで下さい。

2011/04/25

symfony エラーチェック(バリデーション)

php講習 4/25
本日のテーマ
・エラーチェック(バリデーション)

(1)値を渡す先のアクション名.ymlをvalidateディレクトリに置く
input -> confirmなので、confirm.ymlをmember_addモジュールの
validateディレクトリに置く

(2)ymlファイルにチェックのルールを記述
fields:
  nickname:
    required:
      msg: ニックネームを入力してください。

(3)エラーだった場合の遷移先をアクション定義する。
handleErrorアクション名
  public function handleErrorConfirm()
  {
      $this->forward('member_add','input');
  }

(4)tmpファイル(input)にエラーの表示を設定する。
バリデーションヘルパ、エラーメッセージの表示
<?php use_helper('Validation');?>
<?php if ($sf_request->haserror('nickname')):?>
<div style="background-color: #ff8888;">
<?php echo form_error('nickname')?>
</div>
<?php endif;?>

(5)エラーメッセージのデフォルト表示変更(エラーメッセージ矢印の設定を消す)
front/config/setting.yml
    validation_error_prefix:    ' '
    validation_error_suffix:    ' '
・記述が終わったら、symfony cc

(6)エラーとなる値を入れ、エラーメッセージの表示と、
入力値が残ることを確認する。


リダイレクト:post(get)された値は引き継がない
フォワード:post(get)された値を引き継ぐ
・handleErrorConfirmでパラメータが引き継がれている。
・inputテンプレートで受け取っているので表示されている。
$sf_params->get('nickname')

<その他のチェック>
・文字列のバリデーター
    sfStringValidator:
     min:          2
     min_error:    少なくとも2文字入力してください
・メールアドレス
    sfEmailValidator:
     email_error:  このメールアドレスは無効です

・数字のチェック
・チェックの項目は覚えなくてもいい。

<練習>
・掲示板で、ニックネームと投稿に必須入力のチェックを追加

・symfonyで用意されているチェックで足りないのは、DBにある情報とのチェック
ニックネームが重複していないか?

・カスタムバリデータ
    myNicknameValidator:
      nickname_error: そのニックネームは既に使われています。
class myNicknameValidator extends sfValidator作成

・動作確認

<追加の情報>
・バリデートでエラーを呼ぶとき、吐き出されるタグがクラスform_error
setting.ymlまたは、cssのクラス指定でスタイルを変更可能
<div id="error_for_nickname" class="form_error" style="">
このニックネームは既に利用されています </div>

・残りの時間は、課題にバリデートを適用
少なくとも、1つ、カスタムバリデータを作る

・ログインユーザの自分の情報を変更するとき、ニックネームを変更しなければ
DBにはニックネームがあるので、必ず1以上が返る。
(処理作成中)

2011/04/23

php講習 4/22

・午前中は、引き続き自主制作課題
動作確認と、レイアウト調整
セキュリティのチェック追加

・午後から、発表
<コメント>
・ログイン設定、セキュリティは始めの方で組み込む。
 セキュリティのチェックを外して機能確認する。

<その他のコメント>
・レイアウト調整はあとで、時間を取られて進まなくなるので。

・来週から、アクセス制御、エラーチェックの予定。
 但し、今のsymfonyの仕組みが判っていないと、混乱するだけなのでもう一度
 課題を見直しておいて下さい。
・課題で指摘のあった項目について修正

課題のファイルをメールで送ること。
 内容を見てコメントする。

php講習 4/21

・引き続き自主課題の制作

・本日は、ログイン設定とセキュリティの実装を行った。
セッションから情報を取得する処理に変更するまでやるのに1日かかった。
セキュリティ設定をすると、機能確認のデバックに支障があるかと思って、
遅らせていたのが裏目に出た。
どのタイミングでログイン、セキュリティを実装するのか、タイミングが難しい。

2011/04/20

symfonyのsfPropelPager

php講習 4/20

昨日、委員長から教えてもらった「徹底攻略」に記述のあったsfPropelPager
自宅で実装した。今日、午前中MisのPCに設定した。
sfPropelPagerは、一覧表などでデータが大きいとき、ページ毎のデータを
作ってくれるsymfony(Prople)の用意してくれたクラス。

午後
・ページャの設定方法練習
bbs2に適用するときの例
使用するとき使う処理はメールで2ファイル送付されています。
前提として、掲示板の投稿一覧が表示されていること。

・アクション(front/default/index)
<いままでの処理>
$this->comments = CommentPeer::doSelect($c);

<ページャでの処理>(この処理に置き換える)
// pager
// ページあたりのレコード数
$per_page =10;
$page = $this->getRequestParameter('page');
$c = new Criteria();
$c->addDescendingOrderByColumn(CommentPeer::CREATED_AT);

$pager = new sfPropelPager('Comment', $per_page);

$pager->setCriteria($c);
//  現在のページ
$pager->setPage($page) ;
$pager->init();

// print_r($pager);  // 内容確認
$this->pager = $pager;
$this->comments = $this->pager->getResults();


<$pagerオブジェクトの内容確認>

必要なものは既に揃っているので、呼び出すだけ。
    [peer_method_name:protected] => doSelect
    [peer_count_method_name:protected] => doCount
    [page:protected] => 1
    [maxPerPage:protected] => 10
    [lastPage:protected] => 4
    [nbResults:protected] => 35
    [class:protected] => Comment
    [tableName:protected] => comment
    [objects:protected] =>
    [cursor:protected] => 1
    [parameters:protected] => Array

(2)メールで送付されたphpファイルの置き場所
/bbs2/lib/helper/MyPagerQueryHelper.php
(helperフォルダは無ければ作る)
/bbs2/app/front/templates/_pager.php
(パーシャルなので置き場所はあえて書く必要がない?)

(3)テンプレートの変更(default/index)
・テンプレートの最初でヘルパーを呼ぶ
<?php use_helper('MyPagerQuery')?>

・投稿一覧のテンプレートで、一覧表示の前に、pagerパーシャル(_pager.php)を呼ぶ。
このときクエリパラメータも一緒に渡す。(パーシャルがページの切替になります)
今回は必要ないかもしれない部分が含まれていますが、このまま書く。
(一覧表で検索条件が必要になったときに使います)
<?php include_partial('global/pager', array('pager' => $pager,
'query' => parameter_to_query($sf_context->getModuleName(),
$sf_context->getActionName(), $query_parameters)));?>


・ページ処理以外の引数を渡す処理
(一覧表に検索条件のフォームがあった場合、アクションにパラメータを渡す必要がある)
parameter_to_query()   // helperに定義されている。

(4)CommentPeerに関数を追加
// 1ページのレコード数、現在のページ、パラメータ
static public function getPager($perpage, $page, $parameters)
{
 $c = new Criteria() ;
 //  検索条件に入力があれば、Criteriaに追加
 if ($parameters["keyword"] != '' ) {
  $c->add(self::CONTENT, "%".$parameters["keyword"]."%",
  Criteria::LIKE) ;
 }

 $pager = new sfPropelPager('Comment', $perpage);
 $pager->setCriteria($c);
 //  現在のページ
 $pager->setPage($page) ;
 $pager->init();

 return $pager;
}

・以上で、掲示板のデフォルト画面のページャができました。
・なお、興味のある人はプログラムを追って下さい、とのことです。
クラスのソースは以下にあります。
/usr/share/pear/symfony/addon/sfPager.class.php
/usr/share/pear/symfony/addon/propel/sfPropelPager.class.php

・課題に教わったpagerを実装、1時間以上かかった。

・ログイン、セキュリティ設定を実装

php講習 4/19

1-2時間目
・自主課題4日目
午後の中間発表のために、動きを確認。エラーは出ない。
バッチでのデータ取得、crontabに設定し、データが更新されることを確認。

3時間目
・中間発表
 やっぱり、セッキー、委員長、ヤギーの出来はいい。

4時間目
・引き続き発表

<コメント>
・何か編集画面を作る
・コンポーネットの部品を使う
・ログイン画面(セキュリティ、ユーザ)管理を実装する

・ページャの設定
 委員長が実装していたので、やり方を教わった。
 出来れば実装したい。

5時間目
comment_edit作成

6時間目
ログイン設定作成、権限を確認中に時間切れ

ページャの設定を見たがよく判らず、委員長に教わって自宅で作業した。
詳細は後日追記。


2011/04/19

CentOSのコマンド登録

CentOSのコマンドで省略形が登録できます。

毎回「mysql -u user -p -Dstudy」と入力するのが面倒な人向けのコマンド登録方法です。

シェルにalias登録が出来ます。
現在の設定は以下のコマンドで参照できます。
$ alias

また、以下の登録をすると、次回以降「mys」でコマンド実行出来ます。
$ alias mys='mysql -u user -p -Dstudy'

便利な機能ですが、一度ログアウトすると消えてしまいます。
このため、ログイン設定に組み込むことをお勧めします。
ログイン設定は、ユーザのホームディレクトリにあります。
~/.bashrc
このファイルの最後に追加しておきます。これで、次回のログインときでも使用できます。
# User specific aliases and functions
alias mys='mysql -u user -p  -Dstudy'

設定が終わったら、一度ログオフしてログインしなおし「alias」コマンドで登録されている
ことを確認しましょう。
または、以下のコマンドを入力
$ source ~/.bashrc

なお、この設定はユーザごとの設定になります。
* 参考 bash 入門

2011/04/18

symfonyでlogviewer、続き

php講習 4/18

今日は昨日と打って変わって肌寒い

1-2時間目
週末に自宅で作業した内容を反映
バッチ処理
ソート、抽出
環境を合わせる

3-6時間目
クーロンタブにログの差分データ作成シェルを設定
シェルは不得意だ。


バッチ処理によるデータアップロードのテスト
フォームに検索条件を残すように変更
ソート指定のラジオボタン追加
レイアウト調整(CSSがよくわからないため、画面が崩れる)

授業でやっていない範囲の実装は、時間を見て追記します。
明日は午後途中経過の発表なので、資料を整理する予定。

2011/04/15

symfonyでlogviewer、続き

php講習 4/15

自主課題2日目

本日も引き続き自主課題の作成作業。
作業を進めるごとに、概略設計していたところの矛盾が表面化。
あちこちぶつかりながらの作業なので、進捗が遅い。
遅いどころか、後ろに戻ってる?

・ログのアップロード処理を作った。
画像アップの処理と同じ作り。
入力、確認、完了(保存)の間で渡すデータは、ログデータが大きいことを考え、データではなく、ファイル名になった。

・ログの日時が、mySQLのデータタイプdaytimeと合っていない。
そのため、保存のとき変換をかけなければならない。
月:Apr -> 4
時間: hh:mm:dd -> hh , mm , dd
変換処理作成に時間がかかった。
mktime($h,$m,$s,$m,$d,$y)

・テーブル間でカラム名に不一致あり。
DB側の修正とプログラムの修正。
テーブルにテストデータが少ししか入っていないので救われた。
テストデータが溜まってからの変更だと、とんでもないことになった。
xampp環境ではないので、DBユーティリティが使えないのは痛い。

・機能を呼び出すため、URLを入力する代わりにサイドメニューを作成。

・作成途中で気が付いた細かいところを整理。
これから1つずつ片付けて行くための時間が足りない。

・symfonyでは、テーブル名とカラム名は同じにしない。

・4/19(火)PMに途中経過の発表をすることになりました。

2011/04/14

symfonyでlogviewer環境設定

php講習 4/14

自主課題1日目

自主課題の作成作業、ログビューアを作ることにしました。

作業を整理、DBと環境作りから始めました。

詳細はあとで書き直します。

2011/04/13

symfonyでlogviewer概略設計

php講習 4/13

1-2時間目
昨日に引き続き自主課題の概略設計

3-4時間目
・各自の課題発表

<自主課題:ログビューア>
・各種ログをWeb画面で参照する。
サンプルとしてsymfonyのログを参照できるようにする。
ログにコメントが書けるようにする。

<コメント>
・ログの取り込みは自動にした方が実用的
こちらは、ログの取り込みで差分ファイルを用意しないといけない。
symfonyのログは差分ファイルになっていないので差分ファイルを
作る処理をcronで作成する確認が取れなかったため、今回は、
ログファイルのアップロードにしています。
出来れば指摘の通りにしたい。

<その他のコメント>
・カラム名などに意味のない名前は付けない。
カラム名などは誰が見ても分かる名前にする。
・symfonyでは、テーブル名、カラム名にuserという名前は使わない。
その他予約語は避ける。(mySQLの予約語
(他の予約語についてはあとで調べます、たぶん)
・モジュール、アクションの名称は統一する。
モジュール名はcomment_addなど、機能(テーブルにレコードを追加してる
こと)が分かるものにする。
アクションはinput,confirm,resultと、入力の流れを統一する。

5-6時間目
・発表が終わったので、実装を始める
その前に作業の整理をしたが、なかなか整理が進まない。
(何から手を付けていいやら)

2011/04/12

symfony、自主制作課題、企画

php講習 4/12
今日も良い天気です。

1-6時間目
本日より自主課題、明日午後、概要のプレゼンテーション。
来週金曜日までの作成期間。

<自主制作課題概要>

(1)システム概要
・どんなシステムを作るのか
・ターゲットユーザ
・収益モデル

(2)DBテーブル構成

(3)アプリケーションモジュール構成

(4)各モジュールの遷移図

4/13PM企画発表
4/22PM発表

今日は認定日のため、午後ハローワークに行ってきました。

2011/04/11

symfonyで掲示板作成、部品化の復習、セッション

php講習 4/11

・今日は室内の当番だった、動くと暑い。

1時間目
・ログイン画面が出来ていない人は、
メールで送付したログインモジュールをfrontに入れてください。
ログイン後、一般ユーザでmypageが表示されるところで一度環境を合わせます。


2時間目
・アプリケーションを作ったらリライトルール等環境を整えるのは、
デフォルトでやって下さい。
・部品化のところから分からなくなった人が多かったので今日はです。
mypage/templates/layout.phpにヘッダーとフッターをパーシャル化する。

・mypageのCSSが反映されていない。
HTMLを参照するとCSSフォルダの参照は href="/mypage/css/main.css"となっている。
/はCentOS上は/bbs2/webなので、mypage用にcssのリンクを張る。
・パンくずリストのパーシャル化

・今やっていることは、backendと同じレイアウトを作ろうとしているので復習です。
・部品化はもう復習しないので、わからない人は自分で復習して下さい。

・メニューをスロットにする
スロットを読み込みたい場所にスロットを呼ぶ
・テンプレートにスロットの定義

・各テンプレートにメニューを追加することになる。
メニューを部品化
・メニューの内容をパーシャル化する。
<?php include_partial("global/menu");?>
_menu.phpへ内容を移す。

・午後はログインしたあとの処理


3時間目
・front/ログイン画面での練習
  print_r($this->getUser());で情報出力を確認する。
・ヘッダーにセッションで保存したニックネームを表示する
php  $this->getUser()->getAttribute('nickname', null, sfConfig::get('sf_session_name'))
テンプレート sf_user->getAttribute('nickname', null, sfConfig::get('sf_session_name'))

・mypageにログアウトモジュールを作成する
$ symfony init-module mypage logout
・ログアウトの処理は、認証、権限をクリアして、トップページにリダイレクト

・セキュア設定していて、認証されていないユーザがアクセスした場合の処理
symfonyでエラーになる。
default/login
権限を持っていないユーザがアクセスした場合
default/secure
設定していないので、エラー表示が出ている
Oops! An Error Occurred
The server returned a "500 Internal Server Error".
sfController->forward('default', 'login')

・setting.ymlの設定
#    login_module:           default   # To be called when a non-authenticated user
#    login_action:           login     # Tries to access a secure page
#
#    secure_module:          default   # To be called when a user doesn't have
#    secure_action:          secure    # The credentials required for an action

・次の時間でこの部分の処理を作成
mypageにmember_editモジュールを作成
$ symfony init-module mypage member_edit
inputのアクション
inputSuccess.php
パンくずとメニューを表示する。

4時間目
・member_editの処理でやっていることは、今までの処理と変わらない
テーブルからデータを取り出し、入力、確認、保存の流れ
・最初がセッションのメンバIDからテーブルに問い合わせて、あとは同じ流れ
$member_id = $this->getUser()->getAttribute('member_id', null, sfConfig::get('sf_session_name'));

・member_editが出来なかった人は自分で復習して下さい。

5時間目
・comment_listモジュールを作成する
$ symfony init-module mypage comment_list

・comment_listでは、自分のコメント一覧を表示したい
カラム追加
alter table comment add member_id int;
投稿したとき、自分のIDを入れる。

・セッションの値を表示する($this->getUser())

・セキュリティの関数
未認証済みにする     $this->getUser()->setAuthenticated(false);
認証済みかどうか     $this->getUser()->isAuthenticated();
権限を追加する     $this->getUser()->addCredential("member");
権限を持つかどうか     $this->getUser()->hasCredential("member");

・コメント編集で、フォームの前にチェックを入れIF文で分岐
コメントのmember_idとログインユーザのIDが一致していることを確認する。

・ログインして記事を投稿、member_idを設定する。
テーブルにmember_idのデータが入ることを確認する。

6時間目
・セッションからIDとニックネームを取得しているので、投稿の画面にある
ニックネームの入力をセッションからの出力に変更する。
・mypageに何かやるときはチェックする。
・コメント_editにIDを渡して編集している
$ symfony init-module mypage comment_edit
受け取る方で修正IDを受け取っている。
それをコメントテーブルに問い合わせて修正している。
ログインしているとき、別のIDを修正できてしまう。
これを防ぐために、コメントを投稿したIDとセッションのIDを比較する。
異なる場合は、/へリダイレクトする。
(そのコメントの編集権限がない)


今後の作業について
・明日から自主制作
水曜午後から企画の概要を発表:
サービス、DB構成、ページ遷移図(入力、確認、完了)
アプリケーション、モジュールの構成、フロント、バックエンドの機能など。
4/22金 午後発表

最終課題
自主制作課題を最終課題にしてもいい

2011/04/09

eclipseからCentOSのmySQLに接続

・windows上のphp開発環境では、xampp上からmySQLを操作していました。
しかし、symfonyになって開発環境をCentOSに移してから、mySQLの操作はSQL文で直接操作しています。GUIでの操作に慣れているので少し面倒で、GUIで出来ないかと思っていました。
そこで、たまたまeclipse上の環境を見ていたところ、JDBCコネクタ経由でmysqlの接続情報がありました。

・Webで調べた情報で、ローカルPCのeclipseからCentOSのmySQLに接続出来ました。
設定方法のポイントは以下の3点です。

(1)mysql(サーバ)のユーザ情報は、接続先情報も保持しているので、ローカル(CentOSにあるmysqlから見てローカル)以外から接続するためには、ユーザ情報と共に接続先情報の設定も必要。
(2)mysql接続用「JDBCコネクタ」ドライバをeclipseに設定する。
・接続情報はeclipseにサンプルとして付属しています。しかし、ドライバは
(私のインストールしたpleiades 3.6)eclipseには付いていませんでした。
pleiadesには、いくつかセットがあるので、JDBCドライバが含まれるものも
あるかもしれません。
(3)eclipseで接続情報を設定する。
JDBCの画面から「新規」接続すれば、DBを参照・更新出来ます。

なお、この設定は開発環境を想定していますので、セキュリティは考慮していません。
セキュリティを考慮する必要がある場合は、必要な設定をして下さい。


(1)mySQLのユーザ情報の設定・確認
・まず、環境確認のため、WindowsのコマンドプロンプトからCentOSのmysqlに接続します。
(windowsにはxampp環境があり、mysqlクライアントがインストールされていることが前提です)
> mysql -h CentOSのIPアドレス -u user -p
> Enter password:パスワード入力
これで「mysqlにログイン出来れば、そのユーザ(user)はeclipseからJDBCの接続に使うことが出来ます。

・mysqlのログインがエラーになった場合
ERROR 1130 (HY000): Host 'windowsのIPアドレス' is not allowed to connect to this MySQL server
mysqlのユーザがローカル接続用になっています。
このため、JDBCの接続に使うためにはMySQL(サーバ)の設定追加が必要です。

・外部接続用ユーザ設定のため、centOS上からmySQLのrootユーザでmySQLに接続します。
$ mysql -u root
・新たに外部接続用ユーザを設定します。(xpは、外部接続PC)
mysql> GRANT ALL PRIVILEGES ON *.* TO user@"xp"
    -> IDENTIFIED BY 'password' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
・この設定、何故か反映に時間がかかるときがあります。 理由がわかったら追記します。

・なお、CentOSがvmware上でnat接続だと、xpにあたる部分がCentOS上のmysqlから見て、ロ-カルIPではありません。(PCのipconfigで表示されるVMnet8のアドレスです)
PCからvmware上のCentOSにtenletで接続していれば、whoコマンドで接続PCのipが表示されます。このipアドレスを指定して下さい。
またセキュリティを犠牲にするなら%が使えます。詳細はmysqlのマニュアルを参照して下さい。

・設定の確認
mysql> select Host,User from mysql.user;

・ユーザの準備が出来たので、PCのWindowsコマンドプロンプトから確認
> mysql -h CentOSのIPアドレス -u user -p
> Enter password:パスワード入力
これで「mysqlにログイン出来れば、そのユーザ(user)はeclipseからJDBCの接続に使うことが出来ます。

参照元:MySQL のインストールと接続設定 - nova の日記


(2)「JDBCコネクタ」ドライバをeclipseに設定する。
・参照元に手順の詳細がありますので参考にして下さい。
以下は、手順概略です。
mySQLのサイトから、ダウンロードページに行って、
「Connectors」「Connector/J」とたどり「Source and Binaries (zip)」
をダウンロードする。
ダウンロードには、mySQLのサイトへのログインを求められます。
アカウントを持っていない場合は、ユーザ登録をする必要があるかもしれません。
eclipseで使用するドライバなのでwindows用(zip)を落として下さい。
ダウンロードしたら、ファイルを解凍。解凍したフォルダの中にドライバがあります。

私の使ったものは、以下のファイル名でした。
mysql-connector-java-5.1.15-bin.jar

これを、eclipseのフォルダに入れます。
eclipseからあとで参照するのでとりあえずどこでも良さそうです。

参照元:Java初心者入門講座: Java MySQL用のJDBCドライバを入手する方法。


(3)eclipseの接続情報を設定する。
・eclipseの接続情報
メニューから、ウインドウ/設定
設定画面から、DBViewer プラグイン/接続文字列
JDBCドライバ:com.mysql.jdbc.Driver
接続文字列:jdbc:mysql://user@CentOSipアドレス:3306/study
最後の「study」はデフォルト接続のDB名です。

・eclipse画面右上のパースペクティブを開く
その他で、DBViewerを選択
・左にDBツリービューが開くので、
DVBiewerPluginで、右クリックして「登録」
・データベース定義の登録画面にて、JDBCドライバから「ファイルの追加」でダウンロードしたドライバを選択、「次へ」
・接続情報の設定画面にて、接続ユーザ、パスワードを入力、「テスト接続」で「接続に成功しました」と表示されれば、接続テストはOKです。
{次へ」で進み「完了」
これで左のDBツリービューにmysqlのDBが表示されます。

なお、OpenOfficeでもMySQLのデータを参照出来ます。

2011/04/08

symfonyで掲示板作成、セキュリティ、権限

php講習 4/8

・今日は天気が悪いけど、まだ雨は降ってません。


1時間目
・昨日の課題を自習
・1時間以上かけて色々試したり、Webを検索したが、ルーティング情報は
反映されている。しかし、URLの表示は直らない。


2時間目
・投稿(コメント)一覧、戻るリンクを設定
・投稿編集、更新完了画面で、戻るリンクを設定

・写真の表示は対応、編集は未対応

・返信一覧のモジュール作成
$ symfony init-module front reply_list
・アクセス確認
/front_dev.php/reply_list/index

・返信一覧の画面設定追加(default/indexからコピー)
パンくずリスト追加

・コメント一覧に、返信数を表示する。
コメント一覧から、返信一覧にリンクを作成
・コメント一覧、コメント編集のパンくずリスト修正

・(メンバ登録、パンくずリストなし)フロントは使わない。


3時間目
・アクセス制御(ログイン画面)
  セッションでlogin_ynの判断

・front-appにloginモジュールを作成
$ symfony init-module front login
/loginでアクセス出来るようにする。

・メールアドレス、パスワードを受け取るログインフォームを作成
昨日の練習はこれを問題なく作るためだったんでしょうか。
・ログインフォームの飛び先は自分で、受け取ったパラメータ から、
メンバテーブルを読みメンバがいるか確認する。
・メンバテーブルを読む処理は、アクションに記述せず、関数にして
MemberPeerに記述する。
ログインしたメンバの名前を表示して確認する。

・メールアドレス、パスワードをチェックするとき、SQL文(チェック関数)は
memberPeerに関数として定義する。


4時間目
・権限
権限は追加できる
(「,」区切りで[[]]で複数指定できるが今回は使わない。)
・設定前の画面確認
/backend/member_list
・権限の制限設定(モジュール毎の制御では、/mod-id/config/security.yml)
  backend/config/security.ymlの設定
default:
  is_secure: off   -> on
  credentials: [member]
設定したら、symfony ccを忘れずに。
・確認(バックエンド以下がsecureになった)
/backend/member_list
    →ログインせず直接アクセスでエラー
 Login Required
This page is not public.


・ログイン画面で認証できたら、バックエンドに飛ばす処理を追加。
$this->redirect('/backend') ;

セキュリティとしてsymfonyのUserオブジェクトに設定するもの
Authenticated = 認証
Credential    = 権限

securiry.ymlで設定する項目
is_secure = 認証
credentials = 権限

・権限の関数は、通常使うものはテキストにあるものくらい。

<課題> ログイン確認できたら、ログアウト機能を追加
・まず、ログアウトモジュール作成
$ symfony init-module backend logout

・次に、サイドメニューにログアウトを追加、リンク先をログアウトモジュールにする。
(ログアウトしたあとはとりあえず、ログイン画面にしておきました)
・バックエンド側のサイドメニューにログアウト項目追加、リンク先をlogoutにする。
ログアウトしたときは、認証と権限をクリアする。
・フロント側のサイドメニューにログイン項目追加、リンク先をloginにする
・確認
/login
/backend/backend_dev.php

settings.yml
#    login_module:           default   # To be called when a non-authenticated user
#    login_action:           login     # Tries to access a secure page
コメントを外す

5時間目
・バックエンドが表示されない
securty.ymlのadmin権限の書き方の問題だった。

<課題>ログイン処理が出来たので、backendは管理者の設定にする。
・管理者の判断のためメンバーテーブルにadmin_ynカラム追加 varchar(1)
> ALTER TABLE member ADD COLUMN admin_yn varchar(1) ;
> desc member;
$ symfony propel-build-schema
$ symfony propel-build-model
$ symfony cc

・ログインでadmin_yn="Y"ならバックエンドへ
  ログインの処理変更
・テストユーザ設定
> update member set admin_yn='Y';
> update member set admin_yn='n' where id=1;

・ログインユーザのセッションの値セット
ログインしたとき、よく使うデータを入れておく。
セッション内に名前空間を作る 第3引数
$this->getUser()->setAttribute('member_id',$member->getId(),sfConfig::get('sf_session_name'));
$this->getUser()->setAttribute('nickname',$member->getNickname(),sfConfig::get('sf_session_name'));

・ログアウトしたときに、名前空間ごと削除する

・パラメータの受け渡し確認のため、バックエンドのテンプレートにニックネームを表示する。

・ログインするとき
backend-app
権限 admin
credetail

mypage-appにとばす(ログイン画面と同じ)
権限  member
画面はトップページ(掲示板)

$ symfony init-app mypage
$ symfony init-module mypage default

6時間目
・答え合わせ
・mypageのアクセス確認は各自で実施する。アクセス出来ている前提。
(これって結構作業量ある)
・mypage-appのアクセス、/mypageになるように設定
$ cd web
$ mkdir mypage
$ mv my*php ./mypage/
$ cp .haccess ./mypage/
$ cd mypage
$ vi .htaccess
$ vi mypage.php
$ vi mypage_dev.php
$ ln -s /usr/share/pear/data/symfony/web/sf ./sf
$ ln -s ../css ./css
/config/setting.ymlの設定変更(リンクヘルパ用)
all:
    no_script_name:         on       # Enable the front controller name in generated URLs

・セキュリティ設定
security.ymlの設定変更
default:
  is_secure: on
  credentials:  [ member ]
・アクセス確認(エラーになる)
/mypage
Oops! An Error Occurred
The server returned a "500 Internal Server Error".

・バックエンド側の権限設定変更
backend
  credentials:  [ admin ]

<課題>mypage にログインユーザの情報を表示
・ログインのアクションで、情報をセット
$this->getUser()->setAttribute('member_id', $member->getId(),sfConfig::get('sf_session_name'));
$this->getUser()->setAttribute('nickname', $member->getNickname(), sfConfig::get('sf_session_name'));

・mypageのアクションで情報を取得、テンプレートで表示
$this->id = $this->getUser()->getAttribute('member_id', null,  sfConfig::get('sf_session_name')); 
$this->nickname = $this->getUser()->getAttribute('nickname', null, sfConfig::get('sf_session_name'));

・symfonyで残った機能
バリデート(エラーチェック)
応用、プラグイン
・あとは、習うより慣れろってことでしょうか
・いままで習った範囲の知識で出来ること
ユーザごとのコメント一覧
自分のコメントを削除

・symfonyの説明が終わったら、自由課題を2週間ほどやる予定。