2011年4月28日木曜日

4/28覚書

しのさん協力■sfPageFlowを使っての新規作成■

■PROJECT作成「プロジェクト名」

一般ユーザでログインし以下を入力
mkdir プロジェクト名
cd プロジェクト名
symfony init-project プロジェクト名

■Application作成
「front」
「backend」
symfony init-app front
symfony init-app backend

■apacheの設定を変更
suでrootへ変更。

/etc/httpd/conf/httpd.confに以下を記述

vi /etc/httpd/conf/httpd.conf

<VirtualHost *:80>
        ServerName www.プロジェクト名(任意).jp
        DocumentRoot /home/ユーザー名/プロジェクト名/web

        <Directory "/home/ユーザー名/プロジェクト名/web">

               AllowOverride All
               Options -Includes -ExecCGI
        </Directory>
</VirtualHost>

■5.Apache再起動
/etc/init.d/httpd restart
実行

httpd を停止中: [ OK ]
httpd を起動中: [ OK ]

----------------------------------------
■C:\Windows\System32\drivers\etc\hostsに 

127.0.0.1(サーバのIP) www.shonanbbs.com
192.168.0.128 www.プロジェクト名.jp

192.168.0.128 www.プロジェクト名.jp 表示を確認。
----------------------------------------
■symfony設定ファイルのシンボリックリンク作成

cd /home/ユーザー名/プロジェクト名/web/

ln -s /usr/share/pear/data/symfony/web/sf ./sf



◆DB/カラム作成
mysql -u rootで入って作成
CREATE DATABASE enojo;

■MySQLユーザーを作成して権限付与
GRANT ALL ON DB名.* TO ユーザー名@"localhost" IDENTIFIED BY "password";
flush privileges;

◆テーブル作成
■テーブル作成
●member
CREATE TABLE member(id int not null auto_increment primary key);
ALTER TABLE member ADD comment_id int not null;
ALTER TABLE member ADD sei varchar(255);
ALTER TABLE member ADD mei varchar(255);
ALTER TABLE member ADD sei_kana varchar(255);
ALTER TABLE member ADD mei_kana varchar(255);
ALTER TABLE member ADD nickname varchar(255);
ALTER TABLE member ADD pass text;
ALTER TABLE member ADD photo1 text;
ALTER TABLE member ADD gender tinyint(1);
ALTER TABLE member ADD zip_code int(7);
ALTER TABLE member ADD pref tinyint(2);
ALTER TABLE member ADD address1 varchar(255);
ALTER TABLE member ADD address2 varchar(255);
ALTER TABLE member ADD address3 varchar(255);
ALTER TABLE member ADD tel varchar(11);
ALTER TABLE member ADD email varchar(255);
ALTER TABLE member ADD note text;
ALTER TABLE member ADD update_at datetime;
ALTER TABLE member ADD create_at datetime;
ALTER TABLE member ADD del_flg tinyint(1);

●reply
create table reply(id int not null auto_increment primary key);
ALTER TABLE reply ADD comment_id int not null;
ALTER TABLE reply ADD name varchar(255);
ALTER TABLE reply ADD content varchar(255);
ALTER TABLE reply ADD photo1 text;
ALTER TABLE reply ADD photo2 text;
ALTER TABLE reply ADD email varchar(255);
ALTER TABLE reply ADD reply_cnt int;
ALTER TABLE reply ADD create_at datetime;
ALTER TABLE reply ADD del_flg tinyint(1);


●comment
create table comment(id int not null auto_increment primary key);
ALTER TABLE comment ADD comment_id int not null;
ALTER TABLE comment ADD content text;
ALTER TABLE comment ADD categorie int;
ALTER TABLE comment ADD photo1 text;
ALTER TABLE comment ADD photo2 text;
ALTER TABLE comment ADD photo3 text;
ALTER TABLE comment ADD note text;
ALTER TABLE comment ADD access_cnt int;
ALTER TABLE comment ADD create_at datetime;
ALTER TABLE comment ADD update_at datetime;
ALTER TABLE comment ADD del_flg tinyint(1);




■テーブル構造の確認
show databases;
describe member;
describe reply;
describe study;
■テーブルの確認
show tables;

■カラムを削除。
ALTER TABLE member drop comment_id;
ALTER TABLE member drop memo;



◆プロジェクト作成

symfony propel-build-schema
symfony propel-build-model

■web/backendディレクトリ作成
cd /home/ユーザー名/プロジェクト名/web

mkdir backend

mv backend.php backend_dev.php ./backend

cp .htaccess ./backend

■.htaccessの内容を変更

cd backend

vi .htaccess

■RewriteBaseとRewriteRuleを以下のように変更

Options +FollowSymLinks +ExecCGI

<IfModule mod_rewrite.c>
  RewriteEngine On

  # uncomment the following line, if you are having trouble
  # getting no_script_name to work
  RewriteBase /

  # we skip all files with .something
  RewriteCond %{REQUEST_URI} \..+$
  RewriteCond %{REQUEST_URI} !\.html$
  RewriteRule .* - [L]

  # we check if the .html version is here (caching)
  RewriteRule ^$ index.html [QSA]
  RewriteRule ^([^.]+)$ $1.html [QSA]
  RewriteCond %{REQUEST_FILENAME} !-f

  # no, so we redirect to our front web controller
  RewriteRule ^(.*)$ /backend/backend.php [QSA,L]
</IfModule>

# big crash from our front web controller
ErrorDocument 500 "<h2>Application error</h2>symfony application failed to start properly"

■web/backend/backend.phpを以下のように修正

define('SF_ROOT_DIR', realpath(dirname(__FILE__).'/..'));
↓
define('SF_ROOT_DIR', realpath(dirname(__FILE__).'/../..'));

■/home/sheena/hunt/apps/front/config/view.ymlを開き、
title、description、keywords を変更する

終了後symfony cc

■データベースへの接続情報を設定する

プロジェクト名/config/databases.yml を開く

all:
  propel:
    class: sfPropelDatabase
    param:
      dsn: mysql://ユーザー名:password@localhost/プロジェクト名
      encoding: utf8
      
■プロジェクト名/config/propel.iniを開き、以下の2項目を修正する

propel.database.createUrl = mysql://ユーザー名:password@localhost
propel.database.url = mysql://ユーザー名:password@localhost/プロジェクト名

◆sfPageFlow(Model名はlib/model参照。最初が大文字なら合わせる。)
管理者用会員情報
symfony propel-generate-create backend default Member
symfony propel-generate-edit backend default Member
symfony propel-generate-list backend default Member

管理者用コメント管理
symfony propel-generate-list backend comment_edit Comment

ログイン
symfony propel-generate-create front login Member
ログアウト
symfony propel-generate-create front logout Member

一般用新規登録
symfony propel-generate-create front member_add Member

新規投稿
symfony propel-generate-create front default Comment
symfony propel-generate-list front default Comment

返信
symfony propel-generate-create front reply_add Reply 

投稿管理
symfony propel-generate-edit front comment_edit Comment

必要なもの

/lib/helper/
MyUtilityHelper.zip解凍後のMyUtilityHelper.phpでおk

/apps/front/templates
_pager.php

/apps/front/lib
myUser.class.php

actionにある下記をCommentPeer.phpへ移動
    static public function getPager($perpage, $page, $parameters)
    {
        $c = new Criteria();
        //$c->addDescendingOrderByColumn(self::CREATED_AT);
        $pager = new sfPropelPager('Comment', $perpage);
        $pager->setCriteria($c);
        $pager->setPage($page);
        $pager->init();
        return $pager;
    }
    
このままだと編集できないので
<a href="/comment_edit/flow?id=<?php echo $item->getId();?>">edit</a>
を追加

4/25覚書

腰痛きついいいい。ちくしょー。
4時間目から登校。
☆sfPageFlow
めんどくさい投稿、編集、完了を一気にやってくれるプラグイン。

最初の解凍方法で詰まったっす・・・・

ええとまずgenerator.zipを自分のプロジェクト直下にFTPでUP。
mv generator.zip /usr/share/pear/data/symfony/
そのあとsuでrootログインして移動
cd /usr/share/pear/data/symfony/
解凍失敗してたファイルを移動
mv generator bk.generator
再度解凍
unzip generator.zip

あとは教科書通りで。
rootに入ったときはcd /home/で入るよ。ってすっかり忘れてたよ・・・。

課題がBBS焼き直しなのでそのまま入った。
symfony propel-generate-create backend member_add Member
symfony propel-generate-edit backend member_edit Member
symfony propel-generate-list backend member_list Member

書きかけ
if(!$member){
$this->redirect('testmember_list/index')
}
<a href="/testmember_list/index?delete=on&id=<?php echo $item->getId()?>">
<a onclick="return confirm('削除しますか?');" href=

2011年4月25日月曜日

4/25覚書

色々あってかなり間が空いた。その色々は主に金銭面だが。

1時間目
☆エラーチェック
frontにmember_addモジュール作成。
以下記述
<?php use_helper('Validation');?> ←Validationヘルパー呼び出し
<form action="/backend/member_add/confirm" method="POST">
名前:<input type="text"name="name"
value="<?php echo $sf_params->get('name')?>"><br>
<?php echo form_error('name');?>
メールアドレス:<input type="text"name="mail" size="30"
value="<?php echo $sf_params->get('mail')?>">
<?php echo form_error('mail');?>
<br>
<input type="submit" name="send" value="確認">
</form>

1.値を渡す先のaction名.ymlをvalidateディレクトリに置く。
confrim.yml作成
2.validate/action名.ymlにエラーチェックのルールを記述する。
confirm.ymlに以下記述
fields:
  name:
    required:
      msg: ニックネームを入力してください。
  mail:
    required:
      msg: メールアドレスを入力してください。
    sfEmailValidator:
      email_error:  メールアドレスを正しく入力してください。
3.エラーだった場合の遷移先をactionで定義する。
 handleErroraction名で作成する。
  public function handleErrorConfirm()
  {
 $this->forward('member_add' , 'input');
  }

2時間目

4.エラーメッセージを表示させる。
fields:
  name:
    required:
      msg: ニックネームを入力してください。
  mail:
    required:
      msg: メールアドレスを入力してください。

出たけどこの謎矢印はSymfonyが出してるのか・・・。
configのsettings.ymlを以下修正。ALLの#もあったら取ろう。

#    validation_error_prefix:    ' ↓ '
#    validation_error_suffix:    '  ↓'
の#と↓ 、 ↓を消す。

片方だけ入力すると、入力した値は消えずに残っている。SymfonySUGEEEEE。
仕組みはhandelErrorConfirmでforwordが値を内部的に保持してくれている。
それを$sf_paramsが受け取っているから表示できる。

☆応用 if文でエラーチェック。

<?php if($sf_request->haserror('name')):?>
<div style="background-color:#ff0000;">
<?php echo form_error('name');?>
</div>
<?php endif;?>

strictは正規表現のvalidate。ただ、strictをつけると携帯のメールがはじかれる?

数字のvalidater

    sfNumberValidator:
      num_error:    整数を入力してください
      min:            0
      min_error:     値は最小0でなければなりません。
      max:           100
      max_error:    値は100以下でなければなりません。

3時間目

☆比較Validater


4時間目

☆自作Validator
member_addのconfirm.ymlのnameのすぐ後に以下追加
    myNameValidator:
      name_error:    そのニックネームはすでに使われています。


module直下のlibディレクトリに作成。
myname(ymlと同じ)validator.class.php
その中身

<?php

class myNameValidator extends sfValidator
{
 public function execute(&$value, &$error)
 {
  //actionではないので呼び出し処理が必要
  $request = sfContext::getInstance()->getRequest();
  $user = $this->getContext()->getUser;

  $c = new Criteria();
  $c ->add (MemberPeer::NICKNAME,
  $request->getParameter('name'));
  $count = MemberPeer::doCount($c);

  if ($count !=0){
   $error ='このニックネームはすでに使用されています。';
   return false;
  }
  return true;
 }

}

?>

おまけ
出力したエラーメッセージのクラスは以下

<div style="" class="form_error" id="error_for_mail"> メールアドレスを入力してください。 </div>
default→configのsettings.ymlのValidate箇所で変更可能。
main.cssでCSS設定もおk。

以降は自習。validate処理追加していこう。とな。
なんとか自前のmember_addに入れられた・・・はふー。

2011年4月15日金曜日

4/15覚書

腰痛+バイト面接で課題-3日。
さてがんばるか~。
☆制作課題
1.システム概要
・どんなシステムを作るか
・ターゲットユーザー
・収益モデル
等々
2.DBテーブル構成
3.アプリケーション・モジュール作成
4.各モジュールページ遷移図

全く考えてなかった。

2時間目も考えるが見事なまでに何もでない。

1.システム概要
・どんなシステムを作るか
 →アフィリエイト+釣果掲示板
・ターゲットユーザー
 →釣り人(海)LT系
・収益モデル
 →楽天のアフィリ収益
等々
2.DBテーブル構成
まあBBSとほぼ一緒。
3.アプリケーション・モジュール作成
4.各モジュールページ遷移図

で、こんなのできた。

自宅でやります・・・・・・。

テーブル名とカラム名は同じにしないって一言が・・・・・・あれ? 似たようなことを前に聞いた気がする。

2011年4月11日月曜日

4/11覚書

1時間目自習
mypage未作成の人が居るためでらっち奔走。

mypageとかのfront以外のアプリ追加手順はこの日記を参照してほしい。

2時間目
mypageのlayout設定。
CSSはシンボリックリンクでfrontと同じにする。
ln -s ../css cssを使う。

ヘッダーとフッターをpartial化。
layout
<?php include_partial("global/header");?>

_header
<div id="header">
<a href="/">SHONANBBS</a>  
ようこそ<?php echo $sf_user->getAttribute('nickname',NULL,sfConfig::get('sf_session_name'));?>
</div>

あとはパンくずとslotでつける。
ほかレイアウト調整。

3時間目

認証と権限の解説復習。
てかprint_r($this->getUser());こええええ。
丸わかりすぎ。

CCSでヘッダの下に追記
#headerLeft {
width: 200px;
float:left
      }
#headerRight {
width: 200px;
float:right;
text-align:right;
      }

4時間目

mypageにログアウト、indexに遷移する処理。
ここはまんまbackendと同じなので省略~。

sessionからmember_idを元にデータを引き出す。
今日の材料はメールでデータがあるからそれ参考で。

5時間目
commentテーブルにmemberテーブルと紐付けるテーブル追加
ALTER TABLE comment ADD member_id int;

6時間目
comment_editを表示させる。
ケアレスミスに数時間_| ̄|○
action側
<?php

/**
 * comment_edit actions.
 *
 * @package    bbs2
 * @subpackage comment_edit
 * @author     Your name here
 * @version    SVN: $Id: actions.class.php 2692 2006-11-15 21:03:55Z fabien $
 */
class comment_editActions extends sfActions
{
 /**
  * Executes index action
  *
  */
 public function executeInput()
 {

  $comment_id = $this->getRequestParameter('id');
  $this->comment = CommentPeer::retrieveByPK($comment_id);


  if ($this->comment != '' &&
  $this->comment->getMemberId() !=
  $this->getUser()->getAttribute('member_id', null,
  sfConfig::get('sf_session_name'))){
   $this->redirect('http://www.shonanbbs.com');

  }
  return sfView::SUCCESS;
 }
 public function executeConfirm()
 {
  $this->id = $this->getRequestParameter('id');
  $this->content = $this->getRequestParameter('content');

  return sfView::SUCCESS;
 }

 public function executeResult()
 {
  $content = $this->getRequestParameter('content');

  $comment_id = $this->getRequestParameter('id');
  $comment = CommentPeer::retrieveByPK($comment_id);

  $comment->setContent($content);

  $comment->save();

  return sfView::SUCCESS;
 }
}


input
<?php slot('pankuzu');?>
<?php echo link_to("HOME","/mypage")?> > コメント編集<?php end_slot();?>

<?php slot('sidemenu');?>
<?php include_partial("global/menu", array('now' => 'home'));?>
<?php end_slot();?>

登録情報更新
<br>

<div class="tblData">
<?php echo form_tag("/comment_edit/confirm","method=post multipart=true") ?>
<table>
<td>コメント:<?php echo input_tag("content", $comment->getContent() , array("size => 20"))?><br>
<?php echo input_hidden_tag('id', $comment->getId());?>
<input type="submit" name="send" value="確認">
</table>
</form>
</div>

confirm
<div class="tblData">
<?php echo form_tag("/comment_edit/result","method=post multipart=true") ?>
<table>
        <tr>
 <th>名前</th>
 <td><?php echo $content?>
 <?php echo input_hidden_tag('content', $content);?>

 </td>
 </tr>
</table>
</div>
<?php echo input_hidden_tag('id',$id);?>
                <?php echo submit_tag('完了');?>

明日から実習

水曜午後から企画発表

・どのようなアプリにするか
・DB構成
・可能ならページ遷移
・アプリケーション、モジュールの構成

2011年4月8日金曜日

4/8覚書

1時間目
CSS適用ができねえええええ。
とおもったら。
ln -s ../css css
自分のログで大文字で書いてた(テペペロ☆

2時間目
comment_listで
コメントと名前とカテゴリの編集をできるようにする。ヒントはreply_add。
exで画像のようだがそこまではムリポ。

3時間目
☆symfonyのアクセス制御
管理画面、マイページなどのように認証されたユーザで
特定の権限を持つユーザだけが閲覧や操作を行えるようにする。

/bbs2/lib/model/MemberPeer.php
static public function retrieveByPassword($mailaddress,$password) {
  $c = new Criteria();
  $c->add(self::MAILADDRESS, $mailaddress);
  $c->add(self::PASSWORD, $password);
  return self::doSelectOne($c);
 }

4時間目
☆認証
symfonyは、アクセスしているユーザに関する情報はユーザークラス($this->getUser())が持っている。
ユーザクラスに権限の情報を付与・削除することと、各アプリケーションごと、
モジュールごとのsecurity.ymlでアクセス制御を実現する。

認証済みかどうか $this->getUser()->isAuthenticated();
どの権限を持つかどうか $this->getUser()->hasCredential("member");

この二つを主に利用する。

制限のルールを書くのはsecurity.ymlで行う。
/backend/config/security.ymlに以下のように記述
all:
  is_secure: on #認証済みの必要がある
  credentials: [ member ] #必要な権限を設定する
モジュールにもsecurity.ymlを置いて上記のように記述することでモジュールごとの
権限管理を行うこともできる。
あと複数設けることもできるが、orにしたい場合は
credentials: [[member,admin]]のようになる。

backendにlogoutモジュール作成して
ログアウト処理。backendからアウトしてTOPへ。
action側(しか要らない)
public function executeIndex()
  {
 //未認証にする
   $this->getUser()->setAuthenticated(false);
 //権限をクリア
 $this->getUser()->clearCredentials();
 //TOPへ移動
 $this->redirect('http://www.shonanbbs.com'');
   return sfView::SUCCESS;
  }
ログイン処理→ログインできたらログアウト→defaultへ遷移。
ログイン処理+α TOPからのリンク。をやりました。まとめソース↓

5時間目

admin_ynカラム追加してif文で判定。

$this->getUser()->setAttribute('member_id', $member->getId(),sfConfig::get('sf_session_name'));
第3引数はセッション内に名前空間(name_space)を必ず設定。
区切りでセットすることで区切りごと削除が可能となる。
sesstion_nameはプロジェクト直下のconfigのsetting.ymlに記述。

☆練習問題
mypageアプリケーション作成
権限Credentialはmemberを指定
adminとmemberでログインしたあとの遷移を変更。
てか最終的な情報しか残せなかたよ。ごめんよー。
frontのloginモジュール、action側
public function executeIndex()
        {
                $this->mailaddress = $this->getRequestParameter('mailaddress');
                $this->password = $this->getRequestParameter('password');

                if ($this->mailaddress != '' && $this->password != '') {
  //メンバーテーブルに入力されたメールアドレス、パスワードで
  //指定出来る行があるかどうか
  //MemberPeerに$this->mailaddress, $this->passwordの引数を渡す
                 $member = MemberPeer::retrieveByPassword
                 ($this->mailaddress, $this->password);

                 if ($member){

  // ログイン状態にする
  //認証処理は$this->getUser()で受け取れるuserオブジェクトで
  //設定できる。セッション名をいちいち変えなくていい。
  $this->getUser()->setAuthenticated(true);

  //権限をクリア
  $this->getUser()->clearCredentials();
  // 会員情報をセッションにセット
  $this->getUser()->setAttribute('member_id',
  $member->getId(),sfConfig::get('sf_session_name'));
  $this->getUser()->setAttribute('nickname',
  $member->getNickname(), sfConfig::get('sf_session_name'));

   if($member->getAdminYn() == 'y') {

   //admin権限付与
   $this->getUser()->addCredential('admin');
   $this->redirect('/backend');

  }elseif ($member->getAdminYn() == 'n') {

   //ここでは一般会員権限のみ付与
   $this->getUser()->addCredential('member');

   // 会員情報をセッションにセット
   $this->getUser()->setAttribute('member_id',
   $member->getId(),sfConfig::get('sf_session_name'));
   $this->getUser()->setAttribute('nickname',
   $member->getNickname(), sfConfig::get('sf_session_name'));

   $this->redirect('/mypage');
   }
  }
   $this->errormsg = "あてはまるユーザが登録されていません";
 }
                return sfView::SUCCESS;
        }

frontのloginモジュール、index側

<?php slot('pankuzu');?>HOME<?php end_slot();?>

<?php slot('title');?>
TOP
<?php end_slot();?>

<?php slot('sidemenu');?>
<?php include_partial("global/menu", array('now' => 'login'));?>
<?php end_slot();?>

<?php use_helper('Validation') ?>

<?php echo form_tag('login/index');?>
<div class="tblData">

<?php if ($errormsg != ''):?>
<div><?php echo $errormsg;?></div>
<?php endif;?>

<table>
        <tr>
                <th>メールアドレス</th>

                <td
                <?php if ($sf_request->haserror('mailaddress')) :?>
                 style="background-color:#ffcccc;"
                 <?php endif;?>>

                 <?php echo input_tag('mailaddress', $mailaddress, array('size' => 50));?>
                <?php echo form_error('mailaddress');?></td>
        </tr>
        <tr>
                <th>パスワード</th>
                <td><?php echo input_tag('password', $password, array('size' => 50));?>
                <?php echo form_error('password');?></td>
        </tr>
</table>
</div>
                <?php echo submit_tag('ログインする');?>
</form>

mypageログイン時TOP表示。
mypageのsecurity.yml
default:
  is_secure: on
  credentials: [ member ]

action側
public function executeIndex()
  {
   $this->getUser() -> getAttribute('member_id',
NULL,sfConfig::get('sf_session_name'));

 $this->member = MemberPeer::retrieveByPK($member_id);
 //$this->comments = CommentPeer::retrieveByComment_Id($cooment_id)
 return sfView::SUCCESS;
  }

mypageのindex。
<?php slot('title');?>
MYPAGE
<?php end_slot();?>

<?php slot('sidemenu');?>
<?php include_partial("global/menu", array('now' => 'member_add'));?>
<?php end_slot();?>

mypageのaction。
public function executeIndex()
  {
   $this->getUser() -> getAttribute('member_id',
NULL,sfConfig::get('sf_session_name'));

 $this->member = MemberPeer::retrieveByPK($member_id);
 //$this->comments = CommentPeer::retrieveByComment_Id($cooment_id)
 return sfView::SUCCESS;
  }
奇跡といいたい。
でけた。

ていうか現状ではlogoutがbackendしかないからmypageでログアウトするのって
ログインしなおすんだよね・・・・・・権限で判定??

補足設定
backendのsettings.ymlを下記に変更。

#認証できない時はloginページに遷移
    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
sessionの有効期限はsettings.ymlの95行目
# timeout: 1800 # Session timeout, in seconds
だよー。

来週は自分のプロフィールや投稿のみ編集可能にする。
とバリデートするそーな。

自分的お勧め
PHPエラーの意味を教えてくれるところ

2011年4月7日木曜日

4/7覚書

腰痛で火曜休み、今日は歯医者で遅刻。

4時間目

1.返信するの横に詳細を見るのリンク追加。
<?php echo link_to("詳細を見る", "@commentdatail?id=".$comment->getId())?>
2.default/datailでコメント詳細ページ表示
action側
 public function executeDatail()
 {
    //GETで渡されてくるコメントIDとか
    $id = $this->getRequestParameter("id");
    $this->comment = CommentPeer::retrieveByPK($id);
    $this->photo = $this->getRequestParameter("photo");

  return sfView::SUCCESS;
 }

datilSussess.php

<div class="box">
<?php echo $comment->getNickname();?>の投稿<br>

 <?php if($comment->getPhoto()):?><br>
 <?php echo image_tag("/images/comment/".$comment->getPhoto());?><br><br>
 <?php endif;?>
 <?php if($comment->getPhoto2()):?><br>
 <?php echo image_tag("/images/comments2/".$comment->getPhoto2());?><br><br>
 <?php endif;?>
 <?php echo $comment->getContent();?><br>
 <?php echo $comment->getCreatedAt();?><br>
</div>
3.commentテーブルにaccess_cntカラム追加
ALTER TABLE comment ADD access_cnt int;

4.詳細ページを開くごとにアクセス数に+1させて、
shared/access_cntコンポーネントで、アクセス数多い順のコメント5件表示
午前中にreply_cntでやったところらしい。

CommentPeer
 static public function retrieveAccessRanking() {
  $c = new Criteria();
  $c->addDescendingOrderByColumn(self::ACCESS_CNT);
  $c->setlimit(5);
  return self::doSelect($c);
 }

action
 public function executeDatail()
 {
    //GETで渡されてくるコメントID
    $id = $this->getRequestParameter("id");
    $this->comment = CommentPeer::retrieveByPK($id);
    $this->photo = $this->getRequestParameter("photo");


  //現在のアクセスカウントを取得
    $access_cnt = $this->comment->getAccessCnt();

    //取得したアクセスカウントに+1をセット
  $this->comment->setAccessCnt($access_cnt + 1);

  //更新
  $this->comment->save();

    return sfView::SUCCESS;
 }

5時間目上記答え合わせ。


6時間目
exerciseモジュール作成。indexからstage2へgetとpostの処理を再度勉強。
自信が無い人はstage10ぐらいまでgetとpostで送り続けるのをやろう。
これができないと今後ついていけなくなるそうです。

2011年4月4日月曜日

4/4覚書

1時間目~2時間目
☆複数画像UPとヘルパー
できてる人はアンケート
enquete_add
名前
性別(ラジオボタン)
興味のあること(チェックボックス)
コメント
画像
SQL
CREATE TABLE enquete(
id int not null auto_increment,
name text,
gender int,
hobby int ,
content text,
photo text,
created_at datetime,
primary key(id) );

ここで時間切れ。自習だぬー。

3時間目
☆ルーティング
ルーティングとは、URL マッピングとも呼ばれ、URLから判断して
使用するmoduleを決定する仕組み。
アクセスした時点でどこに飛ばすか、のコントロール機能。

場所はプロジェクト/apps/アプリケーション名/config/routing.yml
ルーティング名称(自由):
url: URL
param: {module: モジュール名, action: アクション名}

※default_symfonyの項目は保留
※URLに*でワイルドカード指定おk

ニュースモジュール作成とsymfony cc
symfony init-module front news
return sfView::SUCCESS;

/news/listにURLを変えるとほかページのリンク修正がめんどい。
そのときにルーティングで処理すると一括でできる。
デフォルトのURLを変更したいときにルーティングを使う。必要なければ使わなくてよい。
※入力ルールparamでは:の後、半角スペース必須。
つけたいルーティングは# default rules(ここから下削除不可)の上に置く。

実例
#news/listにURL変更。ルーティングルールは上位ほど強くなる。
newslist:
  url:  /news/list
  param: { module: news, action: index }
routing.yml変更後は必ずsymfony cc
表示しないルールをつけることもできる。
newslist:
  url:  /news
  param: { action: error404 }

IDの受け取り
コントローラー側
  public function executeDatail()
  {
   print $id = $this->getRequestParameter("id");
   //$this->id = $this->getRequestParameter("id");
   return sfView::SUCCESS;
  }
routing.yml側
newsdatail:
  url:  /news/datail/:id
  param: { module: news, action: datail }
http://www.shonanbbs.com/news/datail/33とか
http://www.shonanbbs.com/news/datail/1111とか入れると数字が出てくるよ

@ルーティング名にするとそのルーティング名に則ったURLにできる。
値はGETで示す。

newsモジュールに以下記述


4時間目
部品化
パーシャル
一番簡単な部品化の方法で、主にロジックを含まないテンプレートを部品化する際に使用する。
指定したモジュール名/templatesディレクトリに、_テンプレート名.phpというファイルを作成する。
読み込むコード


実例
layout.phpの<div id="contentRight">直下に記述。

モジュール名にglobalにすると一番上のモジュールを指定できる。
templates直下に\menu.php作成し、
MENU

会員登録

とかを切り取って貼り付け。

◆練習問題
ヘッダーとフッターをpartial化
◆練習問題
sharedモジュール作成、templateはmessageでお知らせ文作成
<?php include_partial("shared/message");?>

_message.php

<div style="boader: 2px; padding: 10px; background-color:#DF8713; margin:10px 0px;">
管理者からの大切なお知らせ。
こちらをごらんください。
</div>

member_addとか無いからlayoutにはっつけちゃったYO。

☆スロット
templateからlayoutを操作したい場合に利用
◆練習。
layoutでtemplate作成。
<div id="pankuzu">
<?php include_slot("pankuzu");?>
</div>
indexSuccessでインクルード。
<?php slot('pankuzu');?>
HOME
<?php end_slot();?>

5時間目
◆練習問題 パンくずを実装
ヘルパー練習ページでも適用できるよ
<?php slot('pankuzu');?>
<?php echo link_to("HOME","/member/list")?>>ヘルパーの練習
<?php end_slot();?>

CSS
#pankuzu {
boder-bottom:1px dotted #ddd;
padding-bottom:5px;
}
◆練習問題 タイトルを変えてみよう
layout.phpの<?php include_title() ?>を
<title><?php include_slot("title") ?></title>に変える
indexSuccessはこう
<?php slot('title');?>
TOP | SHONANBBS
<?php end_slot();?>

◆補足。関数利用可能
titleというスロットがあればtemplateを読み込むifが使える。
<title><?php if(has_slot("title")):?>
<?php include_slot("title") ?> | <?php endif;?>
SHONANBBS</title>

templateがより省略できる
<?php slot('title');?>
TOP
<?php end_slot();?>

◆スロットとパーシャルの組み合わせ

layoutのパーシャル切り取り、以下に変更
<?php include_slot("sidemenu");?>

<?php slot('sidemenu');?>
<?php include_partial("global/menu", array('now' => 'top'));?>
<?php end_slot();?>

ヘルパーページ
<?php slot('sidemenu');?>
<?php include_partial("global/menu", array('now' => 'help'));?>
<?php end_slot();?>

_menu.php
<?php if ($now == "top"):?>
<a href="/" class="nowpage">TOP</a><br>
<?php else :?>
<a href="/">TOP</a><br>
<?php endif;?>

<?php if ($now == "help"):?>
<a href="/default/help" class="nowpage">ヘルパーの使い方</a><br>
<?php else :?>
<a href="/default/help">ヘルパーの使い方</a><br>
<?php endif;?>

6時間目

◆練習もっかいパーシャル。
<?php include_partial("global/ad");?>

<div class="ad">
広告です。
</div>

☆コンポーネント
パーシャルにロジックが加わったものがコンポーネント。
部品化したいが、その部品を作成するためにはデータベースからデータを取得する
必要がある場合に使用される。

◆練習問題
member_listモジュール無い人は追加
sidemenuにmemberlistを出してみよう。

bbs2/apps/front/modules/shared/templatesに_memberlist.php作成

メンバー一覧
<?php foreach ($members as $member):?>
<div class="sidelist">
<?php echo $member->getNickname();?>
</div>
<?php endforeach;?>

bbs2/apps/front/modules/shared/actionsにcomponents.class.php作成
<?php
class SharedComponents extends sfComponents
{
 public function executeMemberlist(){
  $c = new Criteria();
  $this->members = MemberPeer::doselect($c);
 }
}

◆練習問題
最新のコメント5件をsidemenuに出してみよう。

bbs2/apps/front/modules/shared/templatesに_newreplyt.php作成

最新の返信
<?php foreach ($replys as $reply):?>
<div Class="sidelist">
<?php echo $reply->getContent();?>
</div>
<?php endforeach;?>

bbs2/apps/front/modules/shared/actions/components.class.phpの
memberlistの直下に作成

 public function executeNewreply(){
  $c = new Criteria();
  $c->addDescendingOrderByColumn(ReplyPeer::CREATED_AT);
  $c->setlimit(5);
  $this->replys = ReplyPeer::doselect($c);
 }

あと_menuの各項目に<div class="sidelist">つけてねー。
今日は何とかついてこれた~~~~。ふぅ。

んで追加のCSS。適宜応用よろ。

#pankuzu {
boder-bottom:1px dotted #ddd;
padding-bottom:5px;
}
.nowpage {
background-color:#FAB6D6;
padding:1px;
margin-bottom:1px;
}
.ad {
 border:1px solid #ddd;
 padding:10px;
 background-color:#D1DEE0;
}

.sidelist {
 border-bottom:1px solid #ddd;
 padding:5px 0px;
 }

4/1覚書

1時間目
replyに画像追加の続き。
ex.複数画像の続き

2時間目も同様

3時間目
☆ヘルパー

no_script_nameをONにすることでフロントコントローラーがURLに出なくなる。

4時間目
ヘルパー続き

5時間目
ヘルパーをbbs2に適用

6時間目
schema実行後に生成されるomディレクトリの子クラスに変更点を記述。
親クラスには記述しない。

来週はreply以外のデータ参照もあるそうな。

現時点ソース。カテゴリ未完成だよー;
写真複数にするときはphotoカラム追加と
/web/images/comment2とか複数必要だよー。

コントロール側

 public function executeIndex()
 {
  print_r(sfConfig::get('sf_support_mail'));


  //commentテーブル全行表示降順
  //昇順 ->addAscendingOrderByColumn(column);
  $c = new Criteria();
  $c->addDescendingOrderByColumn(CommentPeer::CREATED_AT);
  $this->comments = CommentPeer::doSelect($c);


  return sfView::SUCCESS;

 }


 public function executeConfirm()
 {
  $this->name = $this->getRequestParameter("name");
  $this->coment = $this->getRequestParameter("coment");
  $this->categorie = $this->getRequestParameter("categorie");
  $photo1 = $this->getRequest()->getFile('photo1');
  $photo2 = $this->getRequest()->getFile('photo2');


 // sleepさせてrootで/tmpを見る
 //sleep(10);

 //画像の一時ファイル判定
 if($photo1["tmp_name"] != '') {

  //保存する画像名はセッションID生成し付与
  session_regenerate_id();
  //myUtil::getFileExtで拡張子判別。帰り値は._gif._png._jpg
  $tmpname1 = 'photo1_' . session_id() .myUtil::getFileExt( $photo1["tmp_name"] );
  //web/uploads/tmpへ画像を移動する
  $this->getRequest()->moveFile('photo1',sfConfig::get('sf_upload_dir').'/tmp/'.$tmpname1);

  //templateにパスを渡している
  $this->photo1 = $tmpname1;
 }

  //画像の一時ファイル判定
 if($photo2["tmp_name"] != '') {

  //保存する画像名はセッションID生成し付与
  session_regenerate_id();
  //myUtil::getFileExtで拡張子判別。帰り値は._gif._png._jpg
  $tmpname2 = 'photo2_' . session_id() .myUtil::getFileExt( $photo2["tmp_name"] );
  //web/uploads/tmpへ画像を移動する
  $this->getRequest()->moveFile('photo2',sfConfig::get('sf_upload_dir').
'/tmp/'.$tmpname2);

  //templateにパスを渡している
  $this->photo2 = $tmpname2;
 }



  return sfView::SUCCESS;
 }

 public function executeHelp()
 {
  return sfView::SUCCESS;
 }

 public function executeResult()
 {

  //nameとmailを変数にして渡す。
  $name = $this->getRequestParameter("name");
  $coment = $this->getRequestParameter("coment");
  $categorie = $this->getRequestParameter("categorie");


  //insertのmember
  //インスタンス化。空のオブジェクトを生成。
  $comment = new Comment();
  //変数にした名前とメールを入力。idカラムは自動なので不要。
  //カラムにcreated_at、update_atがあればSymfonyが自動で一緒にやってくれる。
  $comment->setNickname("$name");
  $comment->setContent("$coment");
  $comment->setCategorie("$categorie");
  //insert文発行
  $comment->save();

  //画像データを変数にして渡す
  $photo1 = $this->getRequestParameter('photo1');
  $photo2 = $this->getRequestParameter('photo2');

  //画像の存在判定
  if($photo1 != '') {

   ///uploads/tmp/'.$photo1から画像を取得
   $src = sfConfig::get('sf_web_dir').'/uploads/tmp/'.$photo1;
   //最新(投稿と同一)のidを取得(autoincrement稼動時)
   $saveName = $comment->getId().myUtil::getFileExt($src);
   //TEMPから/images/comment/".$saveNameへ保存
   $dst = sfConfig::get('sf_web_dir')."/images/comment/".$saveName;

   rename($src, $dst);
   $comment->setPhoto($saveName);
   $comment->save();

  }

  if($photo2 != '') {

   ///uploads/tmp/'.$photo2から画像を取得
   $src = sfConfig::get('sf_web_dir').'/uploads/tmp/'.$photo2;
   //最新(投稿と同一)のidを取得(autoincrement稼動時)
   $saveName = $comment->getId().myUtil::getFileExt($src);
   //TEMPから/images/comment/".$saveNameへ保存
   $dst = sfConfig::get('sf_web_dir')."/images/comments2/".$saveName;

   rename($src, $dst);
   $comment->setPhoto2($saveName);
   $comment->save();

  }


  return sfView::SUCCESS;
 }
index

<div class="line">
<?php echo form_tag("default/confirm","method=post multipart=true")?>
新規投稿<br>
<?php echo textarea_tag("coment", 
array("rows" => "10", "cols" => "30")) ?>

<br>
ニックネーム<?php echo input_tag("name", array("size => 20"))?>

   
カテゴリ

<?php $categorie = sfConfig::get('sf_categorie')?>
<?php echo select_tag("$categorie", 
options_for_select($categorie,$value));?><br>

画像1<?php echo input_file_tag("photo1") ?><br>
画像2<?php echo input_file_tag("photo2") ?><br>

<?php echo submit_tag("送信する") ?><br>

</form>

</div>

<div class="comment">
 <?php foreach ($comments as $comment):?>
  <?php echo $comment->getNickname();?>の投稿
     投稿日時<?php echo $comment->getCreatedat();?>
     カテゴリ:<?php echo $comment->getCategorie();?><br><br><br>

  <?php echo $comment->getContent();?><br><br>
  <?php if($comment->getPhoto()):?>
  <?php echo image_tag('/images/comment/'
.$comment->getPhoto(),"class=imgmain") ?><br><br>
  <?php endif;?>
  <?php if($comment->getPhoto2()):?>
  <?php echo image_tag('/images/comment/'
.$comment->getPhoto2(),"class=imgmain") ?><br><br>
  <?php endif;?>
  <?php echo link_to("返信", "/reply_add/input", 
array("query_string" => "id=".$comment->getId()))?>
 <br><br>

<?php $replys = $comment->getReplys();?>
  <?php foreach ($replys as $reply):?>
<div class="reply">

  <?php echo $reply->getNickname();?>さんの投稿
   返信日時<?php echo $reply->getCreatedat();?><br><br>
  <?php echo $reply->getContent();?><br><br>
  <?php if($reply->getPhoto()):?>
  <?php echo image_tag('/images/reply/'.$reply->getPhoto(),"class=imgmain") ?><br><br>
  <?php endif;?>
</div>
  <?php endforeach;?>
 <?php endforeach;?>

</div>
input
このコメントに返信します
<div>
 <?php echo $comment->getContent();?><br>
 <?php if($comment->getPhoto()):?><br>
 <img src="/images/comment/<?php echo $comment->getPhoto();?>"><br><br>
 <?php endif;?>
</div>

<div class="line">
</div>
返信フォーム<br>

<?php echo form_tag("/reply_add/confirm", "method=post multipart=true")?>
<?php echo textarea_tag("coment", array("rows" => "10", "cols" => "30")) ?><br>
ニックネーム<?php echo input_tag("name", array("size => 20"))?><br>
<br>
画像1<?php echo input_file_tag("photo") ?><br><br>
<?php echo input_hidden_tag('id', $comment->getId()) ?>
<?php echo submit_tag("確認する") ?>
</form>
confirm
<?php echo form_tag("/reply_add/result", "method=post multipart=true")?>
返信内容<br>
<?php echo $coment;?>
<?php echo input_hidden_tag('coment', $coment) ?>
<br>
ニックネーム<br>
<?php echo $name;?>
<br>
画像<br>
<?php if($photo !=""):?>
<img src="/uploads/tmp/<?php echo $photo?>">
<br><br>
<div class="line"></div>
<?php echo input_hidden_tag('photo', $photo) ?>
<?php endif;?>
<?php echo input_hidden_tag('name', $name) ?>
<?php echo input_hidden_tag('id', $id) ?>
<br>

<?php echo submit_tag("完了") ?>
</form>

2011年3月31日木曜日

3/31覚書

1時間目

reply_add実装続き

2時間目

reply_add実装

idを引き継ぐ処理以外は基本おなじなのだねー。

ていうかそのreplyを表示させるのががが。

3時間目
画像アップロード

[name] => notice01.jpg
[type] => image/jpeg
[tmp_name] => /tmp/phpyCW55n
[error] => 0
[size] => 83218

ファイル送信時次のプログラムの処理が終わるまでの間、
サーバーのTEMPディレクトリに一時保管されている。

sleep(20);を加えると20秒間処理を止めるので、
その間にPuTTYからrootで入ってcd /tmpで中身を見ると、
-rw------- 1 apache apache 83218 3月 25 16:25 phpJNeLpc
ってファイルがsleepで設定した時間分だけ確認できる。
処理が終われば消える。

4時間目

画像アップロード処理続き
TEMPディレクトリ作成とパーミッション変更

cd web/uploads
mkdir tmp
chmod -R 777 tmp


画像のアップロード
実際に表示させてみる


5時間目
photoカラム追加
ALTER TABLE comment ADD photo text;
schema.yml、model作成
/web/images/commentディレクトリ作成
chmod 777 commentでパーミッション作成

あと画像表示
できたらpreplyも。
replyカラム+/web/images/replyカラムつけてね。

6時間目

あと画像表示
できたらpreplyも
作業続き

めんどいからここでコード。
action.class.php
<?php

class reply_addActions extends sfActions
{
  public function executeConfirm()
  {
   $this->id = $this->getRequestParameter("id");
 $this->name = $this->getRequestParameter("name");
 $this->coment = $this->getRequestParameter("coment");
 $photo = $this->getRequest()->getFile('photo');

   if($photo["tmp_name"] != '') {

  //保存する画像名はセッションID生成し付与
  session_regenerate_id();
  //myUtil::getFileExtで拡張子判別。帰り値は._gif._png._jpg
  $tmpname = 'photo_' . session_id() .myUtil::getFileExt( $photo["tmp_name"] );
  //web/uploads/tmpへ画像を移動する
  $this->getRequest()->moveFile('photo',sfConfig::get('sf_upload_dir').'/tmp/'.$tmpname);

  //templateにパスを渡している
  $this->photo = $tmpname;
 }

 return sfView::SUCCESS;
  }

  public function executeInput()
  {
   //GETで渡されてくるコメントID
   $id = $this->getRequestParameter("id");
   $this->comment = CommentPeer::retrieveByPK($id);
   $this->photo = $this->getRequestParameter("photo");


 return sfView::SUCCESS;
  }

  public function executeResult()
  {
 //idとnameとmailを変数にして渡す。
 $id = $this->getRequestParameter("id");
 $name = $this->getRequestParameter("name");
 $coment = $this->getRequestParameter("coment");

 //replyのupdate
 //インスタンス化。空のオブジェクトを生成。
 $reply = new Reply();
 //変数にした名前とメールを入力。
 $reply->setCommentid("$id");
 $reply->setNickname("$name");
 $reply->setContent("$coment");
 //insert文発行
 $reply->save();

 $photo = $this->getRequestParameter('photo');

  //画像の存在判定
  if($photo != '') {

   ///uploads/tmp/'.$photoから画像を取得
   $src = sfConfig::get('sf_web_dir').'/uploads/tmp/'.$photo;
   //最新(投稿と同一)のidを取得(autoincrement稼動時)
   $saveName = $reply->getId().myUtil::getFileExt($src);
   //TEMPから/images/comment/".$saveNameへ保存
   $dst = sfConfig::get('sf_web_dir')."/images/reply/".$saveName;

   rename($src, $dst);
   $reply->setPhoto($saveName);
   $reply->save();

  }

   return sfView::SUCCESS;
  }
}

inputSuccess.php
このコメントに返信します
<div>
<?php echo $comment->getContent();?>
  <?php if($comment->getPhoto()):?>
  <img src="/images/comment/<?php echo $comment->getPhoto();?>"><br><br>
  <?php endif;?>
</div>

<div class="line">
</div>
返信フォーム<br>

<form action="/reply_add/confirm" method="post" enctype="multipart/form-data">
<textarea name="coment"></textarea><br>
ニックネーム<input type="text" name="name" size="20">
<br>
<input type="file" name="photo"><br>
<input type="hidden" name="id" value="<?php echo $comment->getId();?>">
<input type="submit" value="確認する">
</form>
confirmSuccess.php
<form action="/reply_add/result" method="post">
返信内容<br>
<?php echo $coment;?>
<input type="hidden" name="coment" value="<?php echo $coment;?>">
<br>
ニックネーム<br>
<?php echo $name;?>
<br>
画像<br>
<?php if($photo !=""):?>
<img src="/uploads/tmp/<?php echo $photo?>">
<br><br>
<div class="line"></div>

<input type="hidden" name="photo" value="<?php echo $photo;?>">
<?php endif;?>
<input type="hidden" name="name" value="<?php echo $name;?>">
<input type="hidden" name="id" value="<?php echo $id;?>">
<br>

<input type="submit" value="確認する">
</form>

resultSuccess.php
完了しました。
<a href="/">トップに戻る</a>

パーミッション解説
自分とグループと他人に対してのアクセス権限。
ファイルへの読み(read) 書き(write) 実行(execute)についての権限を与えること。

できる人だけ。
アップロード3つぐらい送って見る。
複数の条件がどーしても思い浮かばない・・・
$photoをどこで複数化するんだああああ。

おまけ
ntpやってなかったので設定。
教科書のサーバー構築の一番下にあるntp設定やればいいよ。
あとcreated_atの表示で詰まった。
_含むばあいは_取っていいみたい。
例】
投稿日時getCreatedat();?>

2011年3月29日火曜日

3/29覚書

1時間目
DBstudyにcontactテーブルを追加
create table contact (
id int not null auto_increment,
name text,
cotent text,
created_at datetime,
primary key(id)
);
※primary key(id)が最初抜けててエラーググって判明;
あぶねー。

schema作成
symfony propel-build-schema
model作成
symfony propel-build-model

lib/modelに
contact.phpとcontactPeer.phpができているか確認。

2時間目

insert復習

actions.class.php
  //insertのcontact。
  //インスタンス化。空のオブジェクトを生成。
  $contact = new Contact();
  //名前と内容を入力。
  $contact->setName('ゆっきー');
  $contact->setCotent('今日はなんとなくやれるかな');
  //insert文発行
  $contact->save();
indexSuccess.php
<div class="tblData">

<table>
 <tr>
  <th>名前</th>
  <th>内容</th>
 </tr>
 <?php foreach ($contacts as $contact):?>
 <tr>
  <td><?php echo $contact->getName();?></td>
  <td><?php echo $contact->getCotent();?></td>
 </tr>
 <?php endforeach;?>
</table>

</div>

updateは省略。
1行削除も省略。
  //全行削除
  $c = new Critreria;
  $contacts = ContentPeer::doselect($c);
  foreach($contacts as $contact){
   $contact->delete();
  }

☆練習問題
contact_addモジュール作成してinsert、confirm、result作成。

3時間目
☆練習問題
contact_addに下記追加。
性別 男性 女性 ラジオボタン
都道府県 prefで
興味のあること チェックボックス

4時間目

もっかいbbs2バックアップしてつくり直し。
んで掲示板reply_addつける。
indexで新規投稿と投稿一覧、各投稿に返信リンク、
新規投稿→confirmで確認→resultで完了
返信リンクid渡し→入力画面id渡し→confirmで確認id渡し→resultで完了

create table reply (
id int not null auto_increment,
comment_id int,
nickname text,
content text,
created_at datetime,
primary key(id)
);

symfony init-module front reply_add
symfony propel-build-schema
symfony propel-build-model
symfony cc
忘れないようにねー

シンボリックリンク
webでln -s /usr/share/pear/data/symfony/web/sf ./sf

ラストまで。

返信の表示処理は明日。
不完全なのでコードは明日。

2011年3月28日月曜日

3/28覚書

1時間目

☆modelによるCRUD(クラッド)
以下の4つの機能を使う。
◆Create
◆Update
◆Delete
◆Read←昨日からやってるデータの呼び出し

◆Create
action側
  //insertのcomment。
  //インスタンス化。空のオブジェクトを生成。
  $comment = new Comment();
  //名前と内容を入力。
  $comment->setNickname('satou');
  $comment->setContent('今日はいい天気');
  //insert文発行
  $comment->save();

  //insertのmember
  //インスタンス化。空のオブジェクトを生成。
  //$member = new Member();
  //名前とメールを入力。idカラムは自動なので不要。
 //カラムにcreated_at、update_atがあればSymfonyが自動で一緒にやってくれる。
  //$member->setNickname("ooyama");
  //$member->setMailaddress("ooyama@sample.com");
  //insert文発行
  //$member->save();

  //最初に必ずセット select * from member;と同じ。
  $c = new Criteria();

View側commentテーブル

<div class="tblData">
<table>
 <tr>
  <th>名前</th>
  <th>内容</th>
 </tr>
 <?php foreach ($comments as $comment):?>
 <tr>
  <td><?php echo $comment->getNickname();?></td>
  <td><?php echo $comment->getContent();?></td>
 </tr>
 <?php endforeach;?>
</table>

</div>

  //$comment+sで複数にする。commentテーブルのすべてのデータを引き出す。
  $this->comments = CommentPeer::doSelect($c);

2時間目
◆Update
Createとの差異は空のオブジェクト生成をしないことだけ。
$member = MemberPeer::retriveByPK();を使う点のみ。
//Update
  $member = MemberPeer::retrieveByPK(5);
  //名前とメールを入力。
  $member->setNickname("ooyama");
  $member->setMailaddress("ooyama@sample.com");
  //insert文発行
  $member->save();

◆Delete
//Delete
  $member = MemberPeer::retrieveByPk(7);
  //memberがあれば削除。こうしないとエラーになる。
  if($member){
   $member->delete();
  }

☆練習問題
1.bbs2でmember_addモジュール作成
2.input、confirm、resultのaction作成
3.resultでinsert処理

1~2は3/23覚書を参考に~。


3時間目
☆練習問題答え合わせ

public function executeConfirm()
  {
 $this->name = $this->getRequestParameter("name");
 $this->mail = $this->getRequestParameter("mail");
   return sfView::SUCCESS;
  }
  public function executeInput()
  {
   return sfView::SUCCESS;
  }
  public function executeResult()
  {
   //insertのmember
 //インスタンス化。空のオブジェクトを生成。
 $member = new Member();
 
 //nameとmailを変数にして渡す。
 $name = $this->getRequestParameter("name");
 $mail = $this->getRequestParameter("mail");

 //insertのmember
 //インスタンス化。空のオブジェクトを生成。
 $member = new Member();
 //変数にした名前とメールを入力。
 $member->setNickname("$name");
 $member->setMailaddress("$mail");
 //insert文発行
 $member->save();

   return sfView::SUCCESS;
  }

4時間目
1.bbs2でmember_list、member_editモジュール作成。
2.モジュール作成。一覧表に編集ページリンクつけて、idを渡す。
3.余裕のある人はdeleteで削除処理

5時間目

作成続き

6時間目
ううむidのReadがどうしても理解できなかった・・・・・・。member_addはさくっとできたのに(つД`)
自力でできなかった人は/bbs2/apps/front/modules/に移動してから、
mv member_list bk.member_list
mv member_edit bk.member_edit
でバックアップとっても一回やろう。

public function executeConfirm()
  {
   //IDを受け取る
 $this->id = $this->getRequestParameter("id");
 //名前、メールアドレスを受け取る
 $this->name = $this->getRequestParameter("name");
 $this->mail = $this->getRequestParameter("mail");


 return sfView::SUCCESS;
  }
  public function executeInput()
  {

   //IDを受け取る
 $id = $this->getRequestParameter("id");
 $this->member = MemberPeer::retrieveByPK($id);
 //名前、メールアドレスを受け取る(オブジェクトごと受け取るときは無しでよい)
 $this->name = $this->getRequestParameter("name");
 $this->mail = $this->getRequestParameter("mail");

 return sfView::SUCCESS;
  }
  public function executeResult()
  {
   //update-member
 //nameとmailを変数にして渡す。
 $name = $this->getRequestParameter("name");
 $mail = $this->getRequestParameter("mail");

 //IDを指定。
 $id = $this->getRequestParameter("id");
 $member = MemberPeer::retrieveByPK("$id");

 //変数にした名前とメールを入力。ここでIDは要らないよ。
 $member->setNickname("$name");
 $member->setMailaddress("$mail");
 //Update実行
 $member->save();

 return sfView::SUCCESS;
  }
insertSucces.php
<form action="/member_edit/confirm/" method="POST">
名前:<input type="text"name="name" value="<?php echo $member->getNickname();?>"><br>
メールアドレス:<input type="text"name="mail" size="30"
 value="<?php echo $member->getMailaddress();?>">

<br>
<input type="submit" name="send" value="確認">
<input type="hidden" name="id" value="<?php echo $member->getId();?>">
</form>
comfirmSucces.php
<form action="/member_edit/result/" method="POST">
名前:
<?php echo $name;?>
です。
<br>
<input type="hidden" name="name" value="<?php echo $name;?>">
メールアドレス:
<?php echo $mail;?>
です。
<br>
<input type="hidden" name="mail" value="<?php echo $mail;?>">
<input type="hidden" name="id" value="<?php echo $id;?>">
<input type="submit" name="send" value="更新する">
</form>
resultSucces.php
完了しました。


おまけ
commentの検索
View側
<form action="/" method="POST">
名前:<input type="text" name="keyword2">
<input type="submit" name="send" value="送信"></form>

action側
  //シンプルなlike検索機能bycomment
  $d = new Criteria();
  $keyword2 = $this->getRequestParameter("keyword2");
  if($keyword2 !=""){
  $d->add(CommentPeer::NICKNAME, "%".$keyword2."%", Criteria::LIKE);
  }
  //$comment+sで複数にする。commentテーブルのすべてのデータを引き出す。
  $this->comments = CommentPeer::doSelect($d);

2011年3月25日金曜日

3/25覚書

1時間目は遅刻

やること
昨日の復習
1.bbs2をbk.bbs2にリネームしてバックアップ
mv bbs2 bk.bbs2
2.front backend mypage
各アプリケーション作成およびdefaultモジュール作成。
3.backendとmypageで/区切りのURLでアクセス
4.frontアプリケーションのレイアウトを変更。

2時間目

1時間目続き。
30分から復習

3時間目
mypageは出るがbackendが出ない。はて。
/bbs2/web/backend/backend.phpの
../../にiが入ってた_| ̄|○
直った。

ちなみにでらっちが/web/main.cssと/apps/front/templates/layout.phpの
中身メールでくれてるよ。昨日とおとといのおいらの記事にもあるけど。
でらっちのみてね~。

member_addはいいのかなあ・・・・・・。

4時間目
retrieveByPK(1);のKは基本

困ったときのデバッグとシンボリックリンク
http://www.shonanbbs.com/front_dev.php
画面が真っ白のときはここを見ればエラーが書いてある。

で、デバッグバーの画像がまだ引っ張れてないので関連付け
bbs2/webで下記実行
ln -s /usr/share/pear/data/symfony/web/sf ./sf

sf -> /usr/share/pear/data/symfony/web/sf
が出ていればデバッグページでF5で出てくるよ。

backendやmypageなどのほかのページには、各ディレクトリへ移動してから
各_dev.phpの../を2個にしておくよ。

ln -s ../sf sf
上の階層(web)からsfを引っ張ってくるよ。

CSSも同じスタイルでよければ
ln -s ../CSS CSS
でつくよ。

セキュリティ上非常に危険なため、リリース前には必ず_dev.phpは削除する。

5時間目
Criteria(クライテリア)による条件指定
WHEREの代わりに使う。

$c = new Criteria();

$c->add(テーブル名Peer::カラム大文字, 指定する値, 条件)
条件を書かない場合はカラム=値と等しい場合となる。
SQL文だとこうなるけど
select * from member whwre id =1;
Symfonyではこうなる

//最初に必ずセット select * from member;と同じ。
  $c = new Criteria();

  //IDが1のデータ
  //$c->add(MemberPeer::ID, 1);

  //member+sで複数にする。1行分のデータを引き出す。
  $members =MemberPeer::doSelectOne($c);

  //指定したIDのみ1行だけ引き出す。
  $member = MemberPeer::retrieveByPK(2);
  //$memberを表示させる。
  //print $member->getNickname();

  print_r ($members);

ソース出すとこうなる。データは配列で受け取る。
Member Object
(
    [id:protected] => 1
    [nickname:protected] => yamazaki
    [mailaddress:protected] => ****@gmail.com
    [password:protected] => 
    [created_at:protected] => 
    [alreadyInSave:protected] => 
    [alreadyInValidation:protected] => 
    [validationFailures:protected] => Array
        (
        )

    [_new:private] => 
    [_deleted:private] => 
    [modifiedColumns:protected] => Array
        (
        )

)

☆DBから名前のデータを引き出す。

action.class.php
  //最初に必ずセット select * from member;と同じ。
  $c = new Criteria();

  //$member+sで複数にする。テーブルのすべてのデータを引き出す。
  $this->members = MemberPeer::doSelect($c);

indexSuccess.php
{を使うとわかりにくいので、:<?php endforeach;?>で囲う。

<?php foreach ($members as $member):?>
<?php echo $member->getNickname();?><br>
<?php endforeach;?>

☆練習問題
名前とメールアドレスをテーブルに出力+CSSで整形

indexSuccessのソース

<div class="tblData">
<table>
 <tr>
  <th>名前</th>
  <th>メールアドレス</th>
 </tr>
 <?php foreach ($members as $member):?>
 <tr>
  <td><?php echo $member->getNickname();?></td>
  <td><?php echo $member->getMailaddress();?></td>
 </tr>
 <?php endforeach;?>
</table>
</div>

MAINCSS
.tblData table {
border-collapse:collapse;
font-size:93%;
margin:5px 0;
}
.tblData th {
background:none repeat scroll 0 0 #EEEEEE;
color:#333333;
font-weight:bold;
padding:5px;
width:120px;
}
.tblData th, .tblData td {
border:1px solid #ddd;
paddig: 5px 10px;
}


6時間目
☆Criteria(クライテリア)による条件指定

条件
Criteria::EQUAL
Criteria::NOT_EQUAL

//最初に必ずセット select * from member;と同じ。
  $c = new Criteria();

  //IDが1のデータ
  //$c->add(MemberPeer::ID, 1);

  //IDがyamazakiのデータ select * from member where nickname ;
  //$c->add(MemberPeer::NICKNAME, 'yamazaki', Criteria::NOT_EQUAL);

  //like指定
  //$c->add(MemberPeer::NICKNAME, "%yama%", Criteria::LIKE);

  //日付指定検索
  //$c->add(MemberPeer::CREATED_AT, "2011-03-01", Criteria::GREATER_THAN);

  //複数条件
  //$c1 = $c->getNewCriterion(MemberPeer::CREATED_AT, "2011-03-01", Criteria::GREATER_THAN);
  //$c2 = $c->getNewCriterion(MemberPeer::NICKNAME, "ya%", Criteria::LIKE);
  //$c1->addOr($c2);
  //$c->add($c2);

  //$member+sで複数にする。テーブルのすべてのデータを引き出す。
  $this->members = MemberPeer::doSelect($c);

忘れてたUPDATE
日付修正ID指定込み
update member set created_at ='2011-03-25' where id =2;
名前文字化け修正ID指定込み
update member set nickname =('名前') WHERE id =2;


☆練習問題 テーブルの上に検索欄追加。余裕のある人はcommentも呼び出して。
indexSuccess側
<form action="/" method="POST">
名前:<input type="text" name="keyword">
<input type="submit" name="send" value="送信"></form>

action側
  //最初に必ずセット select * from member;と同じ。
  $c = new Criteria();
  //シンプルなlike検索機能
  $keyword = $this->getRequestParameter("keyword");
  if($keyword !=""){
  $c->add(MemberPeer::NICKNAME, "%".$keyword."%", Criteria::LIKE);
  }

  //$member+sで複数にする。テーブルのすべてのデータを引き出す。
  $this->members = MemberPeer::doSelect($c);


commentに何も入れてなかった。サンプルに残そー。

insert into comment (nickname,content,created_at) values ('山崎','腰が痛い','2011-03-25');
insert into comment (nickname,content,created_at) values ('みっくみく','ボカロボカロ','2011-03-25');
insert into comment (nickname,content,created_at) values ('サンレッド','コードナンバー046','2011-03-25');
insert into comment (nickname,content,created_at) values ('ウサコッツ','アニマル怪人','2011-03-25');

2011年3月24日木曜日

3/24覚書

1時間目
腰痛&腹痛のため掃除はお休み。
・EclipceでShift+Ctrl+Fキーで勝手に整形してくれる。超便利。
(でも今までの感覚からするとちょっと見づらいかな;)
・☆練習問題解説編
user_addモジュールにinput、confirm、resultのactionを入れよう。
ページの内容は名前を入力→確認→完了の流れで作ろう。
できたらMENUの下に会員登録ってリンクつけてね。

ファイル自体が壊れたりエラーが多い時はPuTTYで削除かディレクトリごと

2時間目

・☆練習問題解説編続き
・メールアドレスの処理を追加
・bbs2にbackendアプリ追加
symfony init-app backend

frontは記事表示を担当。backendで管理機能を担当。
frontコントローラーのリクエストを受けるのはindex.php。
frontアプリケーションのfrontコントローラーはindex.php。

backendコントローラーのリクエストを受けるのはbackend.php。
backendアプリケーションのbackendコントローラーはbackend.php。

backendにdefaultmodule追加
bbs2で以下実行
symfony init-module backend default

2番目以降のURLは省略不可。
ブラウザでアクセスするときは
http://www.shonanbbs.com/backend.php/default/index
SEO的にまずいので/で簡略化だけど3時間目で。

3時間目

アプリ―コントローラーの関係

見栄えの問題やSEO上の考慮から
http://www.shonanbbs.com/backend/default
でアクセスできるように設定する。

1.cd /home/teacher/bbs2/web
に移動

2.backendディレクトリを作成
mkdir backend

3.backend.php backend_dev.phpをbackendディレクトリへ移動
mv backend.php backend_dev.php ./backend

4.htaccessディレクトリをbackendディレクトリへコピー
cp .htaccess ./backend

5.backendディレクトリへ移動
cd backend

6..htaccessの内容を変更する
vi .htaccess
RewriteBaseとRewriteRuleを以下のように変更

8行目
#RewriteBase /の#をとる
22行目
RewriteRule ^(.*)$ /backend/backend.php [QSA,L]
に変更する。

7.backend.phpを開いて下記に変更
3行目
define('SF_ROOT_DIR', realpath(dirname(__FILE__).'/../..'));
/..を1階層増やすだけ。

8.http://www.shonanbbs.com/backend/defaultでアクセスできることを確認。

☆練習問題
mypageアプリを新規追加してbackendと同じようになってみよう。

4時間目

☆練習問題
mypageアプリを新規追加してbackendと同じようになってみよう。

の答え合わせ。

☆YAML
ヘッダー情報はYAML、ymlファイルで管理。
/bbs2/apps/front/config/view.yml

metas:
title: SHONANBBS
に変更し、
symfony cc(CCはキャッシュクリア)
ymlを変更したら必ずsymfony ccを行い、F5でページ更新。

ここの詳しい話は後日。
5時間目
metasの内容を以下に変更。

description: 課題掲示板です。
keywords: WEBエンジニア養成科,php,Symfony
language: ja

変更したらsymfony ccを行い、F5でページ更新。

■出ないとき
キャッシュをクリアする権限をユーザーでなくrootですると、Symfony ccが正常終了しない。
bbs2で
chown -R ユーザー:ユーザー /cache
でキャッシュの権限をユーザーに変更しなおすか、

chown -R755 ユーザー:ユーザー /cache
+パーミッション変更やてみる。


個別に書きたいときは各metasの項目を削除しlayout.phpで直書きか後日行う部品化を使う。

CSSも stylesheets: [main]
標準のCSS正規パス /home/yamazaki/bbs2/web/css/main.cssに存在する。
書き足したいときはカンマ+スペースで区切る
stylesheets: [main, mypage, ・・・]

javascripts: []もある。今はいじらないけど。

has_layout: on

actionの出力結果をレイアウトしなくていいときはoffにできるよ。

layout: layout
layout.phpを使うという意味。名称変更可能。

☆データベース
SQL を使用せずにデータベースを操作する、O/Rマッピングを使う。

O/R マッピングとは、「オブジェクト」と「リレーショナルデータベース」を
マッピング(対応付け)することです。
O/R マッピングは実装時のデータベース操作にかかわる煩雑な作業を軽減してくれます。

SQLのデータの記述はルールが無いため複雑になりやすい。

O/Rマッピングはルールが決まっているので作業効率が上がる。

とりあえずrootでmysqlログインするよー

ログインしたらcreate database study;でDB作成。
show database;でstudyの存在を確認したら

GRANT ALL ON study.* TO ユーザー名@"localhost" IDENTIFIED BY "パスワード";
flush privileges;

ホスト名は同じサーバーならlocalhost、外部からならIPアドレス。

しかし・・・・・・なぜかflush privileges;ができない
ERROR 1146 (42S02): Table 'mysql.servers' doesn't exist
になってしまう。

回避策
use mysql;

を実行し下記コピペ。

CREATE TABLE `servers` (
`Server_name` char(64) NOT NULL,
`Host` char(64) NOT NULL,
`Db` char(64) NOT NULL,
`Username` char(64) NOT NULL,
`Password` char(64) NOT NULL,
`Port` int(4) DEFAULT NULL,
`Socket` char(64) DEFAULT NULL,
`Wrapper` char(64) NOT NULL,
`Owner` char(64) NOT NULL,
PRIMARY KEY (`Server_name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='MySQL Foreign Servers table';

も一回flush privileges;でようやく完了。

6時間目
comment、member、テーブル作成。

create table comment (
id int not null auto_increment,
nickname text,
content text,
created_at datetime,
primary key(id)
);

create table member (
id int not null auto_increment,
nickname text,
mailaddress text,
password text,
created_at datetime,
primary key(id)
);

☆Symfonyでのデータベース接続
/bbs2/config/databases.yml
#をすべて取る。

mysql://root@localhost/dbnameを変更
mysql://ユーザー名:パスワード@localhost/study
エンコード設定とプログラムの記述注意点
YAMLは先頭部分の記述は半角スペース2個をひとつと判断している。
この部分の構成は崩さないように。

all:
  propel:
    class:          sfPropelDatabase
    param:
      dsn:          mysql://ユーザー名:パスワード@localhost/study
      encoding: utf8


/bbs2/config/propel.iniの以下を変更

propel.database.createUrl = mysql://root@localhost/
propel.database.url = mysql://root@localhost/bbs2


propel.database.createUrl = mysql://ユーザー名:パスワード@localhost
propel.database.url = mysql://ユーザー名:パスワード@localhost/study

☆schema.ymlを作成する(DB作成後のみ処理可能)
モデルを作成するための設計書にあたるschema.ymlを作成する。
DBを見に行って接続情報・テーブル情報を引き出し、データファイルを作るための設計書を作成。

一般ユーザーでbbs2から実行。
symfony propel-build-schema

vi /bbs2/config/schema.yml
で中身にcommentテーブルなどが出ている。

次にモデルファイルを作成。
bbs2で実行
symfony propel-build-model

cd lib/modelの中身にcommentPeer.phpとmemberPeer.phpができていればおk。

?? テーブル構造に変化があったらschemaとmodel再生成。
独自追加したい場合はschema.ymlとDB両方とも手書き修正。
自動生成させるとせっかく変えた設定が上書きされてしまう。

7時間目

データ入れます。
set names sjis;
忘れないでねー。

INSERT INTO member (nickname, mailaddress) VALUES
('yamazaki', 's****@gmail.com');
INSERT INTO member (nickname, mailaddress) VALUES
("みっくみく", "mmd@gmail.com");
INSERT INTO member (nickname, mailaddress) VALUES
("サンレッド", "sunred@gmail.com");
INSERT INTO member (nickname, mailaddress) VALUES
("ウサコッツ", "usako@gmail.com");

停電なんでここまで。

2011年3月23日水曜日

3/23覚書

腰痛のため4時間目後半から参加。
詳しくは講習の記録をご参照くだされ。

☆準備でちゃんと聞けなかったところ
actions.class.phpの
public function executeIndex()
indexSuccess.php
太字の箇所は同じ名前にする。

ちょっと言い換えてみる。
actions.class.phpで
public function execute動的処理()
出力処理Success.php
この関係は同じ変数で管理するというイメージがいいのかな。
あと大事なこと。executeの後の項目名は最初大文字で。しないと動かないよ。



☆URLとアクションの関係
Symfonyではモジュール+アクションのページ構成が基本となる。
【例】
member_addモジュールのinputアクションにアクセスするとき。
http://www.shonanbbs.com/member_add/input

あと、Virtualhostの設定間違えてた・・・_| ̄|○ゴメンヨー
<VirtualHost *:80>
    ServerName www.kikin.com
    DocumentRoot /home/kikin/web

    <Directory "/home/kikin/web">
        AllowOverride All
        Options -Includes -ExecCGI
    </Directory>

</VirtualHost>

<VirtualHost *:80>
    ServerName www.shonanbbs.com
    DocumentRoot /home/user(要修正)/bbs2/web

    <Directory "/home/user(要修正)/bbs2/web">
        AllowOverride All
        Options -Includes -ExecCGI
    </Directory>
</VirtualHost

以上を踏まえて練習問題。
☆bbs2にblogモジュールを作って出力。

1.PuTTYから一般ユーザーでbbs2に移動→以下実行
symfony init-module front blog
Eclipceに移動→F5で/bbs2/apps/front/modules/blogができてるよ。

2.そこのaction.class.phpを開いたら、
$this->forward('default', 'module');をコメントアウトか
return sfView::SUCCESS;に置き換えちゃおう。

これの意味の詳しいのは基金訓練WEBで。
基本return sfView::SUCCESS;しか使わないようだけどね。

3./blog/templatesのindexSuccess.phpに何か書いてみよう。

4.http://www.shonanbbs.com/blogにアクセス。


5時間目
CSSのこと。

まあこれもFizzBuzzできてりゃなーんとなくわかると思う。
Symfony+CSS使いはかーなーり、重宝されるそうな。
CSSはテンプレサイトいっぱいあるし、見た目で選べるから楽だよ。

CSSでIDは1ページにひとつだけ。クラスは何個でもOK。
実際に作ってみました。

/bbs2/apps/front/templates/layout.php
ちょっとだけ崩れてるかも。ごめんよう。
<div id="header">
SHONANBBS
</div>

<div id="contentWrappr">
<div id="contentLeft">
<?php echo $sf_data->getRaw('sf_content') ?>
</div>

<div id="contentRight">
MENU
<a href="/member_add/input">会員登録</a>
</div>

<div class="clr"></div>
</div>

<div id="footer">
COPYRIGHT © SHONANBBS
</div>

/* */CSSのコメントアウトだよー。
/bbs2/web/css/main.cssの記述
ちょっと違ってるかもだけどごめん。

/* ヘッダ情報 */
#header {
border-bottom:1px solid #ddd;
margin-bottom:10px;
background-color:#228b22;
}
/* ページ全体のレイアウト */
#contentWrappr {
width:850px;
margin:0 auto;
}
/* 左段落レイアウト */
#contentLeft {
width: 600px;
float: left;
}
/* 右段落レイアウト */
#contentRight {
width: 250px;
float: right;
}
/* フッター情報 */
#footer {
border-bottom: 1px solid #ddd;
margin-bottom:10px;
}
/* フロート処理クリア */
.clr {
clear: both;
}

つかCSS久々過ぎて構文吹っ飛んでたさ・・・。
思い出したら馬鹿さ加減でもうね。・ ゚・。* 。 +゚。・.。* ゚ + 。・゚・(ノД`)

ちょっとメモ。
デバッグ用アドレス*****_dev.php/
【例】front_dev.php/

☆練習問題

user_addモジュールにinput、confirm、resultのactionを入れよう。
ページの内容は名前を入力→確認→完了の流れで作ろう。
できたらMENUの下に会員登録ってリンクつけてね。

ちょwwwレヴェル高杉wwwww
でした。
その前の段階のあることをやってなかったもんで;

同時進行でやるとケアレスミス多発でした。
構文は間違ってないのにページ出ねえぇええええ!

☆どうもPOSTやGETの説明だったみたい。

actionでは
$this->変数 = $this->getRequestParameter("変数");
これだけでPOSTもGETも処理するんだって。

defaultのaction.class.phpに記述。
  public function executeIndex()
  {
 $this->name = $this->getRequestParameter("name");
 $this->address = $this->getRequestParameter("address");
 $this->hobby = $this->getRequestParameter("hobby");
   return sfView::SUCCESS;
  }
で、View側。
HELLO! ENOSHIMA!<br>

私の名前は<?php echo $name;?>です。<br>
住所は<?php echo $address;?>です。<br>
趣味は<?php echo $hobby;?>です。<br>

<hr>

<form action="/" method="POST">
名前:<input type="text" name="name"><br>
住所:<input type="text" name="address"><br>
趣味:<input type="text" name="hobby"><br>
<input type="submit" name="send" value="送信">
</form>

このとき最初は表示されなくて、すごく悩んでいたんでつが・・・気づかなかったんでつよ。
formがfromとか。

なんかね、もう。ばかばかばかばかばかばか。

あとは、別actionのページ作ってください、ってとき。
newsSuccess.phpと書かねばならないところを、
news.Success.phpとか書いてた・・・・・・・・・・・・。


・ ゚・。* 。 +゚。・.。* ゚ + 。・゚・(ノД`)


それからやっとこの意味がわかった。

対応するビューは各モジュールのtemplatesディレクトリに次のような命名ルールで関連付けられています。

アクション名 + ビューの種類.php

わかるとなんでもないことなんだよなああああああああああ。

明日は這ってでも行くんで、腰痛よ、治まってくれ~~~~。


以下超ネタバレ。今後のために自力解決推奨。

1.PuTTY一般ユーザーからbbs2で以下実行
symfony init-module front member_add

2.action.class.phpを下記に変更
  public function executeConfirm()
  {
 $this->name = $this->getRequestParameter("name");
   return sfView::SUCCESS;
  }
  public function executeInput()
  {
   return sfView::SUCCESS;
  }
  public function executeResult()
  {
   $this->name = $this->getRequestParameter("name");
   return sfView::SUCCESS;
  }

3.以下のページ作成
/bbs2/apps/front/modules/member_add/templates/confirmSuccess.php
中身
名前:<?php echo $name;?>です。<br>

<hr>

<form action="/member_add/result/" method="POST">
<input type="hidden" name="name" value="<?php echo $name;?>">
<input type="submit" name="send" value="完了">

</form>

/bbs2/apps/front/modules/member_add/templates/inputSuccess.php
中身
メンバ登録!<br>

<hr>

<form action="/member_add/confirm/" method="POST">
名前:<input type="text" name="name"><br>
<input type="submit" name="send" value="確認">
</form>
/bbs2/apps/front/modules/member_add/templates/resultSuccess.php
中身
完了しました。

4.http://www.shonanbbs.com/member_add/inputでテスト。

2011年3月22日火曜日

3/22覚書

1時間目
1.USBからkikinフォルダをコピー
・rootからkikinユーザー作成(パスワードは任意)
2.FFFTPをあげてkikinで新規ホスト作成。IPアドレスはVMWare playerと一緒
3.接続できたらkikinディレクトリへ1.でコピーした中身をすべてアップロード
4.vi /etc/httpd/conf/httpd.conf
を開き下記追加
<VirtualHost *:80>

    DocumentRoot /home/kikin/web
    ServerName www.kikin.com
    ErrorLog logs/kikin.com-error_log
    CustomLog logs/kikin.com-access_log common

    <Directory ~/home/kikin/web~>
        AllowOverride All
        Allow from All

        Options -Includes -ExecCGI
    </Directory>
</VirtualHost>
ちょっと上にあるNameVirtualHost *:80の前の#取ってね。

5.Apache再起動
/etc/init.d/httpd restart
実行

httpd を停止中: [ OK ]
httpd を起動中: [ OK ]

ってなればおkだよ
6.C:\WINDOWS\system32\drivers\etc\hosts\hosts.confをエディタで開いて
192.168.***.***(自分のIP) www.kikin.com
を入れて保存。

2時間目
開始8分で停電。
今後の課題用WEBアプリの設計図を作成。
自分の好きなこと、やりたいことでおkだけど、思いつかない人はブログ。

3時間目
お昼挟んで停電復旧。
1~2時間目でやりきれなかった処理を終わらせる。

4時間目
パーミッション変更コマンド
cd /home/でhomeディレクトリに移動して、以下コマンド実行
chmod -R 755 kikin
kikinディレクトリのパーミッション(アクセス権)を775に変更する。

cd /home/kikin/config/
でディレクトリ移動し、
vi config.php
でconfig.phpを開く。
su - kikin
でkikinユーザーへ移動し、
symfony fix-perms
でパーミッション修正。
symfony cc


5時間目
cd /home/kikin/web/
に移動
tar -xvzf img.tar.gz
で解凍
一般ユーザーへ変更し以下を実行
mkdir bbs2
bbs2ディレクトリ作成
cd bbs2
bbs2ディレクトリへ移動

symfony init-project bbs2
symfonyプロジェクト作成


アプリケーションファイル作成
symfony init-app front

アプリケーションの中にデフォルトモジュール作成
symfony init-module front default


6時間目

vi /etc/httpd/conf/httpd.conf
を開いて下記追加
<VirtualHost *:80>
        ServerName www.shonanbbs.com
        DocumentRoot /home/自分のユーザー名/bbs2/web

        <Directory ~/home/自分のユーザー名/bbs2/web~>
                AllowOverride All
                Options -Includes -ExecCGI
        </Directory>
</VirtualHost>

/etc/init.d/httpd restart
で再起動


リモート・システム・エクスプローラー

リモート・システム・エクスプローラーは、Eclipse3.4で新設された機能。
Eclipseのワークスペースの外のディレクトリーやファイルを参照できる。
(要するにWindowsのエクスプローラーやftpツールと同じ)
リモート・システム・パースペクティブ

メニューバーの「ウィンドウ(W)」→「パースペクティブを開く(O)」→「その他(O)」で
「リモート・システム・エクスプローラー」を選択すると「リモート・システム」パースペクティブが開く

左側ウィンドウで右クリック→新規→接続→SSHのみでOK→ホスト名は自分のIP。
貼り付ければ接続名も勝手に入る。ID/PASS保存チェック。で完了。

確認メッセージはすべてはい。
/home/ユーザー名/bbs2/apps/front/modules/defalut/actions/actions.class.phpを開き、
$this->forward('default', 'module');を削除して
return sfView::SUCCESS;に置き換え。
/home/ユーザー名/bbs2/apps/front/modules/defalut/actions/indexSuccess.phpに
hello enoshima!
とでもいれませう。
保存したら次にPuTTYで一般ユーザーでbbs2フォルダへ移動し、
symfony fix-perms
symfony cc
実行。
これでhelloでたらおk。

※なぜかうまくいかーん状況。
理由はタイプミスですた;
cd apps/front/modules/
でモジュールの中見たらdefalutになってた_| ̄|○
rm -rf defalut/でリネームして落ち着きますた。

明日は地震の埋め合わせの開講。木曜日3/24と5/9は7時間授業やるぞー。

2011年3月11日金曜日

3/11覚書

1時間目
いよいよサーバー構築。
まずは準備

★Firewall設定
SELinux( エスイーリナックス)解除。
ELinuxとは強制アクセス制御 (MAC) 機能を付加するモジュールの名称。
Linuxデフォルトのセキュリティソフト。
これがあるとサーバーの動作、つか学習の邪魔なので無効化して止めます。

VMWare player起動→PuTTYをrootでログイン
◎vi /etc/sysconfig/selinuxを実行。
◎6行目にSELINUX=enforcing(有効)とあるので

◎SELINUX=disabled(無効)に変更。
行数は:set numberでわかるよ!

◎rebootでCent OS再起動を命令。これをしないと設定が反映されない。
PuTTYいったん終了
Cent OSでログイン画面が出たらPuTTYでrootログイン。
getenforceを実行してdisabledと出れば成功。違ってたら◎やり直し。

以下から1行ずつコピペでEnter。一文字でも間違えるとサーバー機能喪失で大変なのでコピペ。

iptables -P INPUT ACCEPT
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

#ルールクリア
iptables -F

#icmp(ping) と自端末からの入力を許可
iptables -A INPUT -p icmp -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT

#Web、FTP、POP、smtp による接続を許可
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -p tcp --dport 110 -j ACCEPT
iptables -A INPUT -p tcp --dport 25 -j ACCEPT

#ssh による接続を許可
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

#TCP の接続開始と応答、FTP データなどを許可
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#ルールをセーブする
/etc/init.d/iptables save

vi /etc/sysconfig/iptablesを開いて
INPUT ACCEPT [51:3934](数字は各自異なる)になっていればおk
INPUT DROPの場合はACCEPTに変更

2時間目
★Apacheの設定

Apacheとはhttpを利用するために必要なプログラム。
yum -y install httpd
でインストール。
yum →インストール用コマンド
-y →確認メッセージをすべてYESにするオプション。
httpd →Apacheソフトウェアのインストーラー

Complete!で終了。

RUNレベル設定 →Linuxの動作モードレベルのこと。
Windowsスタータップと捉えておk。たいていは7つ設定。
基本は2-5に切り替えるが、実行させたら自動で割り当ててくれるので気にしなくていい。

/sbin/chkconfig httpd on
/sbin/chkconfig --list httpd
httpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
ってなってればおk
できたら
/etc/init.d/httpd start
/etc/init.d/httpd restart
の順で実行。OKが出れば大丈夫。

★MySQLインストール

yum -y install mysql-serverを実行。
completeまで待つ。
出たら
vi /etc/my.cnfで設定ファイルを開く。
[mysqld]の下に下記追加。
default-character-set = utf8
skip-character-set-client-handshake
character-set-server = utf8
collation-server = utf8_general_ci
init-connect = SET NAMES utf8
さらに[mysqld_safe]の項目の下に追加。

[client]
default-character-set = utf8
[mysql]
default-character-set = utf8
[mysqldump]
default-character-set = utf8

そしてRUNレベル設定。
/sbin/chkconfig mysqld on
/sbin/chkconfig --list mysqld

mysqld 0:off 1:off 2:on 3:on 4:on 5:on 6:off
ってなってればおk。
そんでMySQLサーバー起動。
/etc/init.d/mysqld start
MySQL を起動中: [ OK ]
mysqldのdはdemon、裏側で実行するプログラム、プロセスと同意義。
MySQLの動作を支える縁の下の力持ち

そしたらプロンプトと同じように
mysql -u root
rootで入る。パスワードはまだ決めてませんので、ていうか
いままでのMySQLと動いている場所が違うので、既存ユーザーは使えません。
データもありません。これから作ります。


★vsftpdのインストール
サーバーにFTPプロトコルのリクエストを受け取るためのプログラム
HTTPとは別にアップロードに必要。
yum -y install vsftpd
completeで完了。

/sbin/chkconfig vsftpd on
/sbin/chkconfig --list vsftpd

vsftpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
こうなってたらおk

3時間目
★FFFTPにVMWareの接続設定を保存。
接続名はVMWare。IPアドレスはPuTTYのifconfigで確認だよ。
ユーザー名はPuTTYで決めた一般ユーザーとパスワードを使うよ。


☆うまく接続できなかった場合☆
vfftpdの設定不備かSElinuxの設定不備のどちらかの可能性高し。


★PHPインストール
yumで入れるとVer5.1になってしまうので、手動インストールで最新Verへ。
取得先のGPG-KEY 取得
rpm --import http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka
DL先の設定
vi /etc/yum.repos.d/utterramblings.repo
を実行し、開いたら中は何も無いので下記コピペ
内容はDL先をローカルからサーバーに変更する。
[utterramblings]
name=Jason's Utter Ramblings Repo
baseurl=http://www.jasonlitka.com/media/EL$releasever/$basearch/
enabled=1
gpgcheck=1
gpgkey=http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka
保存したらつぎ~

yum -y install php
でphpインストール。下も続けて1行ずつ
yum -y install php-devel
yum -y install php-common
yum -y install php-gd php-mbstring php-pdo php-mcrypt php-mysql php-ncurses php-xml

php -vでVer確認
PHP 5.2.16 (cli) (built: Dec 17 2010 14:09:03)
でおk

★Symfonyインストール
yum -y install php-pear
pear channel-discover pear.symfony-project.com
pear install symfony/symfony-1.0.20

symfony -V(大文字)で
symfony version 1.0.20と出れば完了

開発環境準備ここまで

PuTTY、VMWare、FFFTP終了。
VMWare再起動したらCent OSを削除。
自力でCent OS再インストールして。
今日やったこと全部自力でやり直せ。と。

4時間目

再インストール続き。
面倒だから工程省略。
IP変わらなかったんでPuTTY設定生きるよ。
PuTTYセキュリティ警告。出たらここははいで通した。めんどいから。

ここから地震のため混乱;

5時間目
2回目reboot忘れたからFTPログインできなかった・・・reboot2回目後正常。
作業完了。

6時間目
再インストール一通り終わったら、自分のIPをブラウザで入れてApacheが出るか確認。
出たら

cd /var/www/html/
でhtmlフォルダに移動。
vi index.html
作成したらhello! world!と入れて保存。
ls -al
でファイル確認。
IP開きなおすと、index.htmlで保存した文字が出てくる。

以上をゆっきー&ばおさんへレクチャーして終了。
バーミッションの設定とかどうなるのかなー。

2011年3月10日木曜日

3/10覚書

大前提:フォルダという表記は今後ディレクトリにします。

1時間目
vi新規作成から、前回の復習。

2時間目
PuTTY即ログイン
ただしwindws、OSのログインパスワード、セキュリティが確立している状態でのみ推奨。
デスクトップにputtyのショートカットを作成
ショートカットを右クリックし、プロパティをクリック
リンク先を以下のように修正し、OKをクリック
"C:\Program Files\PuTTY\putty.exe" -load 接続セッション名 -l "ユーザ名" -pw "パスワード"
そのショートカットをランチャーに設定すると、毎回ユーザ情報を入力する必要がなくなります。

それからclnchへそのショートカットドラッグ。名前は自分でわかれば何でもおk。

そんでホットキー設定。
CraftLaunch(クラフトランチ)だよ。
以下ランチャーと呼ぶよー。
入れたらクリックしてCキーを押せばConfigが出るから十字キーで選択してEnter。
ホットキー割り当て選択してEnter。
Ctrl+Shift+Spaceキー同時押ししてC-S-Spaceと画面にでたらEnter。
確認方法はランチャー以外の箇所をクリックするとランチャーに日付と時刻が出るよ。
Ctrl+Shift+Spaceキー同時押ししてランチャーが黒くなれば成功だよ。
いちいちクリックしなくていいから楽ちんなのだ。


残りの時間はviの操作の練習。
画面移動Shift+H(high)、M(middle)、L(Low)

3時間目
vi操作続き

文頭、文末の処理がちょいと面倒だね。
そんなときのためにShift+$があるんだけどねー。
ただ、endキーで慣れてるんでちょっと使いづらいねえ。
ちなみにvi側で選択=コピーのキャッシュはこっち側で貼り付け可能だよー。

上級者向けつかいいんちょから。
vi コマンドリファレンス

☆UNIXコマンド

|パイプ
【例】ls -al |wc 
wcはファイルの行数、単語数、サイズを表示
|(パイプ)でつなげて結果を表示させる。
>リダイレクション
【例】ls -al > test.txt
>はリダイレクト。コマンド情報をファイルに出力できる。
vi test.txtで開くとls -alの内容が中に記述されている。
【例】ls -al |wc > test2.txt
というふうにつなげることもできる。
wcの結果をtest2.txtに出力させるという命令。

ディレクトリ移動
cd(カレントディレクトリの意)
cd ..でひとつ上の階層へ。

/home/yamazaki
[yamazaki@localhost ~]$ cd ..(いっこ上の階層)
[yamazaki@localhost home]$ pwd(現在地表示)
/home
[yamazaki@localhost home]$ cd ..
[yamazaki@localhost /]$ pwd
/

戻り方は2通り。どちらでも同じディレクトリを開く。
[yamazaki@localhost ~]$ cd /home/yama
[yamazaki@localhost ~]$ cd ../yama
直前のディレクトリに戻るのに、cd -もできるよー。

★豆知識★
ls -alしたときに右端の文字が青かったらディレクトリを示す。
赤かったら圧縮されている。

ディレクトリ作成
mkdir ディレクトリ名

ファイルの削除
rm ファイル名

ディレクトリごと削除するにはオプション -rを付ける
rはrecursive(再帰的)の略
rm -r ディレクトリ名

ファイル(ディレクトリ)移動
mv ファイル(ディレクトリ)名 移動先
【例】mv yama1.txt /home/yamazaki/yama1/

ファイルコピー&別ディレクトリへ移動
【例】cp 0310-01.txt yama1.txt | xargs mv yama1.txt /home/yamazaki/yama1/

4時間目
catコマンド
内容表示。
【例】cat test4.txt
長いファイルの場合は|moreで1画面を出し、Enterで1行ずつ見える。
【例】cat test4.txt | more

headコマンド
ファイルの先頭内容10行を見ることができる。-nで行数指定可能。
【例】head -n 3 yama1.txt

tail -f リアルタイムにファイルの末尾内容10行を見ることができる。-nで行数指定可能。
サーバーのログファイルをチェックするときに使う。
【例】tail -f -n 3 yama1.txt

ファイルの圧縮、解凍
複数指定もこんな感じで。
【例】tar -cvzf ptest.tar.gz test2.txt test3.txt test4.txt

cronコマンド
今はコマンドの元が無いので使えませぬ。

findコマンド
検索機能。
場所も名前もわからないときは【例】find / -name ファイル名で検索すればいいのだ。
日付で出すのも有効。
今のぼくらは【例】find ./ -mtime -1で出てくるのだ。
昨日作ったばかりだからね。

5時間目
grepコマンド
検索対象の文字とファイル内容が一致するか検索
練習準備
yama1、2、3のディレクトリにtest.txt作成。
内容は
test
hello
nya
nyanya
を適当に入れる。入れる項目はすべて同じにはしません。ちょっとだけ変えます。
grep -r -l test ./
今のディレクトリすべてを対象に、testという言葉が入っているか調べて、
パターンに一致した行を含むファイル名だけを出力する。
ほかhelloやnyaでも調べる。

lnコマンド
Windowsショートカットと一緒
classや画像のインクルード時に活用。
ln -s リンク元( 実体) リンク名
【例】ln -s yama1 ya1

duコマンド(rootで入ってから操作)。
指定したディレクトリ内の全てのファイルとディレクトリサイズを確認する時に使う。
【例】du -k /var
ディレクトリ全体のサイズを確認する場合はオプション sをつける。
【例】du -s /var
ファイルサイズをわかりやすくするには-hをつける。
【例】du -s -h /var

killコマンド
プロセス強制終了。
各プロセスはtopで確認。右端のCOMMANDだよ。

wgetコマンド
直ダウンロード&サーバーうp

xargs(エックスアーグズ)コマンド
xargsは、標準入力から受け取ったものを引数として、他のコマンドを起動するコマンドです。
【例】find ./ -name "hello*" | xargs rm -f
今のディレクトリからhelloを含むものを探し、さらに削除します。
発展系
【例】find ./ -type d -name "yama" | xargs ls -la
今のディレクトリからディレクトリ名にyamaを含む項目のみリスト表示します。

6時間目
今日の復習

vi終了したーい:q!だたね; いまいち掴めん・・・。
コマンド入力中にEnterしちゃった→Ctrl+Cで抜けます。

IDManagerをメモ帳代わりにすると今後楽。
ホットキーCtrl+I+OでIDManager起動できるお。

おすすめサイト

UNIXコマンド推奨。

いまさらxargsの便利さを主張してみる
条件にヒットしたファイルを ~/backup にコピーする
Loadaverageが50以上?はてな掲示板より 例題のような感じ。
ロードアベレージが86.29 実体験の様子。

2011年3月8日火曜日

3/8覚書

1時間目
お掃除。
VMWAREとCentOSのインストール。
ファイルサイズがGB単位なのでUSBメモリでコピー。
っても待ち時間にVMWAREはDLした。
さすがにUSBが一個なので時間かかる・・・・・・。

2時間目
ファイルコピー終わらず・・・・・
USB2個あればなぁwwww

3時間目
vmware とは、クライアントのマシンに仮想サーバを構築するためのソフト。
開発現場でも、vmware で個人用開発環境を構築し、
そこで開発したプログラムを本番環境に移すという開発フローを取っている人が多い。

vmware playerのインストール
* vmware playerをダウンロードする
* ダウンロードしたVMware-player-3.1.2-301548.exeをクリックしインストールを開始する
* すべて「次へ」で最後にパソコンの再起動を行なう
* デスクトップに出来ているvmware player のショートカットをクリックし起動する。

次回からは起動してCent OS選択して仮想マシンの再生→PuTTYで実行。

CentOSのインストール

コピーしたCentOS-5.5-i386-bin-DVD.isoを
マイドキュメントに生成されたMy Virtual Machinesへドラッグ。
マウスカーソルの動作はCent OSかWindowsか切り替えが必要。
Cent OSから戻るときはCtrl+Altで抜ける。
サーバー管理者パスワードは6文字以上で設定。
細かい手順は訓練サイトみて。
☆POINT
【Desktop-Gnome】のチェック除外→Cent OSのデスクトップ画面を使わない。
つかサーバーなんだし要らないよ。重くなるし。現場環境に合わせるのだ。
【今すぐカスタマイズ】で選択し左メニューから【開発】、右のセレクトボックスで
【レガシーなソフトウェアの開発】と【開発ツール】、【開発ライブラリ】にチェック
これをしないとコンパイルの際にライブラリが無いといわれてしまう。

4時間目
rootでログイン。さっき決めたパスワード(非表示)を入力して
root@localhostが出たら成功。
ifconfigを入力してinet addrの192.168.~をメモ。
putty起動してホストにメモった192.168.~を入力。ポートはデフォルト22まま。
セッション接続名は任意だがVMWAREとでもつけて保存。
そして開き、またrootとパスワード(ここも非表示)

Cent OSはあまりいじらないが、
root(管理者)ユーザーのままだと危険なので別ユーザーを作る。

☆以降PuTTYで操作。
PuTTYでuseradd 半角ユーザー名。変化無ければ作成成功。
パスワードはpasswd ユーザー名で変更可能
パスワードを聞かれるので2回パスワードを入力する
exitでPuTTY終了。PuTTY再起動で設定したユーザー名とパスワードでログイン。

あとセッション切れ防止のための処理。
まずは設定したセッション選択して読み込み。


左側メニューの接続からkeepaliveの数値を300に変更して、
セッションを再度選択して保存。


☆文字化け時の対策はUTF-8(CJK)を選択。変換と同じ処理で保存オヌヌメ。

su(switch userコマンド)で追加したユーザになり、自分のルートディレクトリを表示する
ちなみに[ユーザー名@localhost~]$は一般ユーザー。
[ユーザー名@localhost~]#は管理者です。


ユーザー変更は
su ユーザー名で変更。suだけだとrootへスイッチ(ただし権限は元ユーザーのまま)。
ここからexitすると元のユーザーに戻る。
su -を実行するとスイッチ先のユーザーの権限(環境変数)へ移行できる。

【練習】
・ユーザーを新規追加。

5時間目

VI操作
UNIX 環境の標準テキストエディタ
特徴
* コマンドモードとテキスト入力モードがある。
* 独特なキー操作
* 軽い
他にemaxというエディタもあるが、VIが標準装備。
コマンド
pwd 自分のディレクトリ表示
ls -al自ディレクトリのファイル一覧を表示


vi test.textで作成。最初はコマンドモードなのでテキスト入力モードへ切り替え。
iキーで変更可能。ESCでコマンドモードに変わる。
保存はESC押してから:wq!で保存され、コマンドモードに戻る。小文字でコマンドと認識。
wq(Write & Quit)!(強制)
vi 既存ファイル名(拡張子必須)で既存ファイルが開ける。

6時間目
Hキー:左
Lキー:右
Kキー:上
Jキー:下

キーボードでカーソル移動。マウスが無かった時代に
ホームポジションでカーソル移動ができるようにした工夫。
文字がある箇所のみ→キーで次の行に移動できるが、
文字が続いていない場合はJキーで下げる必要がある。

文字挿入はESCでコマンドでカーソル移動、iキーで挿入、ESCでコマンド移動
おまけに行が続くとJキー/Kキーで下の行えらべねええええええ。

コピー&ペースト
コピーしたい箇所を選択するだけでコピーされ、右クリックで貼り付け
行数表示
:set numberで行数表示/:set no numberで非表示

補完機能
ファイル名の先頭文字を入れてTabキーを押すと補完し、複数の場合は候補表示してくれる。

ていうかここ参照でいいような。
細かい解説
viコマンド リファレンス

その中間かな?解説
vi / vim コマンド一覧

大きな文字でやさしく解説
viエディタでの編集・操作コマンド

2011年3月7日月曜日

3/7覚書

1時間目
二次元配列の肝がキタ━━゚+.ヽ(≧▽≦)ノ.+゚━━ ッ ! ! !
kuku.php

require( "./libs/Smarty.class.php" );
$smarty = new Smarty();

for ($i = 1; $i < 10; $i++) {
 for ($j = 1; $j < 10; $j++) {
  //二次元配列の生成
  $num[$i][] = $i*$j;
  }
}

$smarty -> assign( "num", $num );
$smarty -> display("kuku.tpl");

kuku.tpl

<html>
<head>
<meta http-equiv="Content-Type" content="text/html"; charset="UTF-8" />
</head>
<body>

<table border=1>
<caption>九九の段・二次元配列</caption>
 <tr>
 {foreach from = $num item = n}
  {foreach from = $n item = c}
  <td height="25" width="25" align="center">
  {$c}
  </td>
  {/foreach}
 </tr>
 {/foreach}
</table>
</body>
</html>
$num[$i][]にすることで二次元配列となる。
[$i]
☆1~9までの数字が入る
[]
☆入れ子のforが回るたびに$i*$jの値が追加されていく
$num[$i][1(1*1)][2][3][4][5].....
[$i][2(2*1)][4][6][8][10].....
[$i][3(3*1)][6][9][12][15].....



2時間目
二次元配列を元にBBSのreplyも出すよー。

方法は二つ。
whileを入れ子にする。
→この方法はやぎーに聞いてくだしあ;
whileを入れ子にしない。
おいらはこっち。
【必須】commentのidとreplyのidを紐付ける。

index.php
require( "./libs/MySmarty.class.php" );

//mysql に接続する
require_once './db_connect.php';

// クエリを送信する
$sql = "SELECT * FROM comment where delete_flg = 0 order by created_at desc";
$result = mysql_query($sql);
while ($row = mysql_fetch_array($result)) {
 $data[] = $row;
}

//クエリを送信する(返信テーブル)
$sql = "SELECT * FROM reply where delete_flg=0 order by created_at desc";
$result1 = mysql_query($sql);

while ($row2 = mysql_fetch_array($result1)) {
 $repdata[] = $row2;
}

$smarty = new MySmarty();
$smarty -> assign( "index_list", $data );
$smarty -> assign( "reply_list", $repdata );
$smarty -> display( "index.tpl" );

//print_r($data);
//print_r($repdata);

index.tpl
<!-- 投稿内容 -->
{{foreach from = $index_list item =num}}
 <div style="border:1px solid #ddd;margin-bottom:10px;padding:5px;">
 {{if $num.url neq NULL}}
 <a href="{{$num.url}}">{{$num.nickname}}</a> さんの投稿
 {{else}}{{$num.nickname}}さんの投稿
 {{/if}}
  
 {{if $num.mail1 neq NULL}}
 <a href="mailto:{{$num.mail1}}">メール</a>
 {{/if}}
   <a href="./delete.php?comment_id={{$num.id}}">削除</a>
 <br>
 {{$num.content}}
 <br>
 {{if $num.photo neq NULL}}
 <IMG SRC="./img/{{$num.photo}}" width=200>
 {{/if}}
 <br>
 <br>
 {{if $num.photo2 neq NULL}}
 <IMG SRC="./img2/{{$num.photo2}}" width=200>
 {{/if}}
 <br>
 {{$num.created_at}}
 <br>
 <a href="reply.php?comment_id={{$num.id}}">返信する</a>
 </div>

 <!-- 返信内容 -->
  {{foreach from = $reply_list item =num2}}
   {{if $num2.comment_id eq $num.id}}
   {{*commentのidとreplyのidを紐付ける。*}}
 <div style="border:1px solid #ddd;margin-bottom:10px;padding:5px;
  background-color:#f3f3f3;margin-left:40px;">
 {{if $num2.url neq NULL}}
 <a href="{{$num2.url}}">{{$num2.nickname}}</a> さんの投稿
 {{else}}{{$num2.nickname}}さんの投稿
 {{/if}}
  
 {{if $num2.reply_mail neq NULL}}
 <a href="mailto:{{$num2.reply_mail}}">メール</a>
 {{/if}}
   <a href="./reply_delete.php?comment_id={{$num2.id}}">削除</a>
 <br>
 {{$num2.content}}
 <br>
 {{if $num2.reply_photo neq NULL}}
 <IMG SRC="./reply_photo/{{$num2.reply_photo}}" width=200>
 {{/if}}
 <br>
 <br>
 {{if $num2.reply_photo2 neq NULL}}
 <IMG SRC="./reply_photo2/{{$num2.reply_photo2}}" width=200>
 {{/if}}

 <br>
 {{$num2.created_at}}
 </div>
   {{/if}}
  {{/foreach}}
{{/foreach}}

3時間目
残りも片付けるよー。

4時間目
if文を使わない方式。こっちのほうがデータ処理が早い。

4次元配列
//SELECT文を発行し、commentテーブルからレコードを取得
$sql = "SELECT * FROM comment WHERE delete_flag = 0 ORDER BY created_at DESC";
$result = mysql_query($sql);

while ($comment = mysql_fetch_array($result)) {
 $row = array();
 //配列変数$rowの要素[comment]に配列$commnetが入るので、この時点で$rowは二次元配列
 $row['comment'] = $comment;
    //SELECT文を発行し、replyテーブルからレコードを取得
    $sql = "SELECT * FROM reply WHERE delete_flag = 0 AND comment_id = 
'".$comment["id"]."'ORDER BY created_at DESC";
    $result1 = mysql_query($sql);

    if($result1) {
        while ($reply = mysql_fetch_array($result1)) {
         //配列変数$rowの要素[reply]の下にもう一つ配列を作り、
         そこに配列$replyが入るので、この時点で$rowは3次元配列
            $row['reply'][] = $reply;
        }
    }
 //配列変数$rowsに3次元配列$rowを格納するので、$rowsは4次元配列
    $rows[] = $row;
}

# 多重配列の表示確認
/*
print"<pre>";
print_r($rows);
print"</pre>";
*/

$smarty = new Smarty;
$smarty->assign('rows', $rows);
$smarty->display('index.tpl');

index3.は3次元だそうな。
デザイナーの負担にならないように構築することで、Smarty本来の機能を発揮できる。

階層イメージ
$rows━━
    ┗$row
      ┣comment
      ┣reply━
          ┣0
          ┣1
$smarty.session.~でsession使えるよ。

マジでくわっちょおわり~。

" ゚☆,。・:*:・゚★o(´▽`*)/♪Thanks♪\(*´▽`)o゚★,。・:*:・☆゚ "
" ゚☆,。・:*:・゚★o(´▽`*)/♪Thanks♪\(*´▽`)o゚★,。・:*:・☆゚ "
" ゚☆,。・:*:・゚★o(´▽`*)/♪Thanks♪\(*´▽`)o゚★,。・:*:・☆゚ "

2011年3月4日金曜日

3/4覚書

1時間目
FizzBuzz~
display忘れてたさ・・・・・・_| ̄|○
fizzbuzz.php
for ($i = 1; $i < 101; $i++) {
 $num_list[$i] = $i;
}
require( "./libs/Smarty.class.php" );
$smarty = new Smarty();
$smarty -> assign( "num_list", $num_list );
$smarty -> display("fizzbuzz.tpl");

fizzbuzz.tpl

<head>
<meta http-equiv="Content-Type" content="text/html"; charset="UTF-8" />
</head>
<body>

<table border=1>
<caption>FizzBuzz。3の倍数はFizz。5の倍数はBuzz。公倍数はFizzBuzz</caption>
 <tr>
 {foreach from = $num_list item = num}
 <td>
 {if $num is div by 3}Fizz{/if}
 {if $num is div by 5}Buzz{/if}
 {if (($num is not div by 3) && ($num is not div by 5))}{$num}
</td>
{/if}
</tr>
{/foreach}
</table>
</body>
</html>

2時間目
FizzBuzz続き~
出るには出たんだけど、trタグの位置がわからんかった。゜(゚´Д`゚)゜。
九九で多少は理解できるのかなあ・・・・・・。
プログラムは上から順に処理するが、Smartyでは上から順に処理される。
elseifを使うときはphpとは逆に記述しよう。

分離の意義。
HTML(tpl)とPHPの作業でどのようになってくるか。を理解するため。

3時間目
メモリ増設。私のはLatitude:D520。celeron Mゆえに最大2GBまでしか効かない。
しかもキーボードカバー外してからDIMM Aスロットがありやんの・・・
いいんちょに外し方てもらいつつやりかたを教わり、しのさんのやってみた。できた。
外し方はメーカーサイト参照。

4時間目~ラスト

BBSをBBS_Smartyにコピーして分離作業+メモリ増設続き。

投稿分だけはでましたが・・・・・・返信難しいよおおお><

理解がないのが悔しい。
明日釣りだけど考えます。ちっくしょー。

2011年3月3日木曜日

3/3覚書

ちょいと遅刻して午後から。自分のドジっぷりがなんだかなあ;

1時間目?
現場レベルでのSmartyのデリミタの扱いについて。
{}はJavaScriptでも使うので、Smartyと混在するとエラーの原因になるので、
回避のためにデリミタを変更したclassを継承させる。

/**********************************************************************

Smartyクラスを継承したMySmartyクラスを作成

コンストラクタの呼び出しが「Smarty()」ではなくて「__construct()」に
変わっているので注意

**********************************************************************/

include_once ( "Smarty.class.php" );

class MySmarty extends Smarty {
 function MySmarty() {
  $this -> left_delimiter = "{{";
  $this -> right_delimiter = "}}";
  $this -> __construct();
 }
}

2時間目?

Ex.SmartyでFizzBuzz。ifとforeachでつくろ~(宿題らしい)。
ファイル名はまんまfizzbuzz.phpとfizzbuzz.tpl。

3時間目

暗号化
md5()で暗号化処理の関数です。覚えておくとラッキー。

mysql_fetch_array = 通常配列+連想配列
楽だがデータ取得が2倍になるので多用は難しい。
mysql_fetch_assoc = 連想配列

mysql_fetch_row = 通常配列


ブラウザで出すとこうなる。エクセルの表をイメージするとわかりやすいかな。
Array//$dataの配列
(
[0] => Array//$rowの1行目の配列
(
[1] => Array//$rowの2行目の配列
(

4時間目
連想配列を表で出してみよう。
foreachelse ・・・・・・データが入っていない場合の判定を入れることでエラー表示回避。

<body>
<table border="1">
 <tr><th>No.</th><th>会員ID</th><th>パスワード</th><th>有効/無効</th></tr>
 {{foreach from = $member_list item = num}}
 <tr>
  <td>{{$num.member_id}}</td>
  <td>{{$num.member_name}}</td>
  <td>{{$num.password}}</td>
  <td>{{if $num.delete_flg == 0}}有効{{/if}}
  {{if $num.delete_flg == 1}}無効{{/if}}</td>//elseifもおk
 </tr>
 {{foreachelse}}
 <tr><td colspan="4">データがありません</td></tr>
 {{/foreach}}
</table>

5時間目
4時間目の内容で、POSTされたデータを扱う。
何がきても大丈夫なように|escape()を使うことでXSS対策になる。
「escape」は「htmlspcialchars」のこと~。
あとindex.tplから。
$blog.blog_date|date_format:'%Y年 %m月 %d日 %T'
でデータの日付表示を変更できるよ。
関数を使うときは|でつなげるよ。

【問題】0302問題
以下のログインフォームをMとVに分離してください
・login.php
・login.tpl

テンプレートファイルに
・ログインネーム($login_name)と
・ログインメッセージ($login_message)
を表示させてください

多分pho側にSmarty設定を入れるのは平気だと思う。
{{$login_name}}と{{$login_message}}だけ~(設定次第なので{}のひとつでもおk)