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の便利さを主張してみる