Posted in Footprints + Diary | By tarotoast | Tags: media-chaos, shitty news, taiwan
最近每天去看新聞時候,每次又會看到誰被性侵,哪個叔叔又姦了自己的姪女,或者哪個女兒勇敢的逃離父親的魔掌。台灣是充滿這些事情的意思嗎?還是想要讓所有正在成長的國小國中生注意說一不小心自己就會是下個受害者?新聞內容描述的也有夠清楚,是要讓其他犯罪者看注意下次犯罪時候別犯同樣的錯才不會被抓嗎?我都不知道還有什麼可以說了,只能感嘆台灣的媒體怎麼可以亂成這種程度。
我一向認為媒體是台灣的亂源,當然先決條件是認同台灣實很亂。媒體的亂象在幾年前已經讓鄉民們受不了而成立了媒亂板 (media-chaos) 來抱怨,但這幾年來社會的劃分也只有跟著媒體的炒作變得更加嚴重而已。講難聽點,雖然有意識到媒體素質亂七八糟,大多數的人還是一樣被牽著鼻子走,很開心的做著沒有大腦的牛。
我今天看到一篇民視的報導,標題是 儉樸? 吳伯雄LV衫露”馬”腳! 以下是轉貼的本文:
儉樸? 吳伯雄LV衫露”馬”腳! 2008/06/07 

馬總統不是在提倡儉樸嗎?但昨晚國民黨主席吳伯雄和僑胞朋友們餐敘,卻被媒體補捉到,他穿了件高檔名牌襯衫,要價一萬多塊錢!雖然兒子立委吳志揚說,是朋友送的,但是不少民眾還是不以為然,認為官員們根本是說一套做一套,一點都不簡樸!
節 能減碳的口號呼的響,讓當今政壇最流行的單品,非短袖襯衫莫屬啦!瞧瞧,國民黨主席吳伯雄,以身作則,只不過呀,再近點看,哇賽!這可不是名牌 LV最經典的logo花色嗎?雖然可能不是吳伯雄自己買的,但是我們發,其實這 件LV襯衫,早在一年前,就已經公開亮相過了!二度穿同一件襯衫出席公開場合,看來,吳伯雄對這件LV,應該挺厚愛的吧!雖然立委兒子說,吳伯雄對對時尚 霧煞煞啦!但是LV牌子,國際上響鐺鐺,見過這麼多世面的伯公,應該不會不知道吧!而且實地詢問LV,這的確是2007年春夏款,而且要價一萬三千多塊錢 耶!和新政府提倡的簡樸,壓根扯不上邊!看在老是穿幾十年舊西裝的馬總統眼裡,要他情何以堪呀!
這篇文章的目的是啥?是要指出國民黨的人都穿 LV 不簡樸來降低執政黨的形象,還是讓反對執政黨的人顯得只懂得找這些無干緊要的事情來抹黑?不管如何,公職人員也是人,人家想要穿什麼是他的事情,一個新聞媒體拿這個來做文章而且還加入了許多扁低對方的想法,這樣的媒體還不算爛嗎?
“啦!” “哇賽!” “這可不是 “應該” “耶!” 這篇下來有幾個驚嘆號?11 個!!!!!!!!!!!想表達作者對這件事情的驚訝嗎?想加強這件事情是多麼的不可思議多麼的不應該多麼的應該受到社會關注嗎?因為讀了這篇而認為吳伯雄是個垃圾的人,本身也不會有什麼自我思考和理解的能力,只能一味被像這種垃圾報導牽著走而已。
像馬英九上任後接二連三來的去台灣事件們可以報,也應該讓社會大眾注意,但是報導的內容又加入了許多這種試圖對讀者洗腦的批判時候,那報導跟新聞台本身就爛掉了。一個充滿了偏激批判的新聞,只會讓人覺得這是有預設立場下所得到的結論,不值得去參考。很可悲的這種誇張的批判大多都是出現在明顯偏綠的媒體。這是在讓大家知道親綠的人都是喜歡看這種文章嗎?愛台灣就是得去計較對方是不是穿 LV,把對方盡力的塑造成一個丑角嗎?這好可悲。
這類的爛新聞台灣很多,只是今天剛好看到這篇民視實在很受不了。
Read more |
6 Comments » |
June 8th, 2008
Posted in Symfony | By tarotoast | Tags: code, database, note, orm, php, propel, symfony
總之,ORM 就是可以省下寫 database specific SQL 的麻煩的 abstraction 就是了。Symfony 用的是 Propel,是一個 PHP5 的 database framework,跟 ADOdb 是類似的東西,雖然兩者到底詳細差在哪我也不知道。不過總之 Symfony 的作者們決定用 Propel 來省下許多 code generation 和實作 ORM。
有幾個非常重要的檔案必須編輯好才能使用 Symfony 裡面的 propel 功能。
- myproject/config/databases.yml
- myproject/config/propel.ini
- myproject/config/schema.yml
老實說 propel.ini 和 schema.yml 為啥要有兩個檔案,我也不知道 (as of now)。總之兩個檔案都得把 database 的設定寫進去就是了。然後 schema.yml 才是整個 ORM 的重點,Symfony 就是讀這個檔案生出所有 database object class 的。習慣直接編輯 schema.yml 的話是會很方便,不過老實說我也還不習慣,所以都用 phpmyadmin 先把 database 生好然後再讓 Symfony 生出 schema.yml。
database.yml
all:
propel:
class: sfPropelDatabase
param:
dsn: mysql://username:password@localhost/database
propel.ini (上面)
propel.targetPackage = lib.model
propel.packageObjectModel = true
propel.project = myproject
propel.database = mysql
propel.database.createUrl = mysql://username:password@localhost/
propel.database.url = mysql://username:password@localhost/database
大致的生產順序如下:
- 產生 schema.yml (自己編輯或者讓 symfony 照著建好的 database 生)
讓 symfony 照著 database 生出 schema.yml:
symfony propel-build-schema
- 產生 ORM classes
symfony propel-build-model
用這個 schema.yml 當範例
propel:
blog_article:
_attributes: { phpName: Article }
id:
title: varchar(255)
content: longvarchar
created_at:
blog_comment:
_attributes: { phpName: Comment }
id:
article_id:
author: varchar(255)
content: longvarchar
created_at:
會生出 8 個檔案,4 個檔案在 lib/model/om/ 下面 (Base Class):
- BaseArticle.php
- BaseArticlePeer.php
- BaseComment.php
- BaseCommentPeer.php
然後另外 4 個檔案在 lib/model/ 下面 (Custom Class):
- Article.php
- ArticlePeer.php
- Comment.php
- CommentPeer.php
生在 lib/model/om/ 下面的檔案只要每次跑 propel-build-model 就會重新被蓋過,所以如果要自己修改 model 增加功能的話,就得修改 lib/model/ 下面的 class。在 Base class 裡面所有 field 的 accessor 都會被自動生出來,也就是說上面這個 yml 生出來的 model 可以這樣使用。
// 單純是示範怎麼用 primary key
$articles = ArticlePeer::retrieveByPks(array(123, 124, 125));
// 使用 setter/getter
$article = new Article();
$article->setTitle('My first article');
$article->setContent('This is my very first article.\n Hope you enjoy it!');
$article->save();
$title = $article->getTitle();
$content = $article->getContent();
// 這才是 ORM 的精華
$comments = $article->getComments();
要如何 Query 比較複雜的判斷呢?答案是用 Criteria 這個 class。以下這段的功能:
$c = new Criteria();
$c->add(CommentPeer::AUTHOR, 'Steve');
$c->addJoin(CommentPeer::ARTICLE_ID, ArticlePeer::ID);
$c->add(ArticlePeer::CONTENT, '%enjoy%', Criteria::LIKE);
$c->addAscendingOrderByColumn(CommentPeer::CREATED_AT);
$comments = CommentPeer::doSelect($c);
其實就等於 SQL 下面的:
SELECT blog_comment.ID, blog_comment.ARTICLE_ID, blog_comment.AUTHOR,
blog_comment.CONTENT, blog_comment.CREATED_AT
FROM blog_comment, blog_article
WHERE blog_comment.AUTHOR = 'Steve'
AND blog_article.CONTENT LIKE '%enjoy%'
AND blog_comment.ARTICLE_ID = blog_article.ID
ORDER BY blog_comment.CREATED_AT ASC
常用到的 condition 可以參考這個列表:
| SQL |
Criteria |
| WHERE column = value |
->add(column, value); |
| WHERE column <> value |
->add(column, value, Criteria::NOT_EQUAL); |
| Other Comparison Operators |
|
| > , < |
Criteria::GREATER_THAN, Criteria::LESS_THAN |
| >=, <= |
Criteria::GREATER_EQUAL, Criteria::LESS_EQUAL |
| IS NULL, IS NOT NULL |
Criteria::ISNULL, Criteria::ISNOTNULL |
| LIKE, ILIKE |
Criteria::LIKE, Criteria::ILIKE |
| IN, NOT IN |
Criteria::IN, Criteria::NOT_IN |
| Other SQL Keywords |
|
| ORDER BY column ASC |
->addAscendingOrderByColumn(column); |
| ORDER BY column DESC |
->addDescendingOrderByColumn(column); |
| LIMIT limit |
->setLimit(limit) |
| OFFSET offset |
->setOffset(offset) |
| FROM table1, table2 WHERE table1.col1 = table2.col2 |
->addJoin(col1, col2) |
| FROM table1 LEFT JOIN table2 ON table1.col1 = table2.col2 |
->addJoin(col1, col2, Criteria::LEFT_JOIN) |
| FROM table1 RIGHT JOIN table2 ON table1.col1 = table2.col2 |
->addJoin(col1, col2, Criteria::RIGHT_JOIN) |
Read more |
No Comments » |
May 26th, 2008
Posted in Symfony | By tarotoast | Tags: access, credential, login, note, php, restriction, symfony
雖然說其實翻翻文件就知道要改哪裡,在這邊記錄下來也只是方便自己不用再回去翻。其實在 Symfony 裡面要實作 Access Restriction (存取限制?) 很簡單,真的只是改 2 個 yml 檔案而已:
- apps/myapp/modules/mymodule/config/security.yml
- apps/myapp/config/settings.yml
apps/myapp/modules/mymodule/config/security.yml 定義著每個 module 下面 action 的存取限制。如果 is_secure = on 的話那就必須要有被認證過 (在 action 下面被 $this->getUser()->setAuthenticated(true);) 才能存取,不然的話依照另一個檔案的設定會被導到預設的 login page。
如果有設定 credentials 的話那除了必須要 authenticated 以外還得有被 addCrendential 過才行。
read:
is_secure: off # All users can request the read action
update:
is_secure: on # The update action is only for authenticated users
delete:
is_secure: on # Only for authenticated users
credentials: admin # With the admin credential
all:
is_secure: off # off is the default value anyway
apps/myapp/config/settings.yml 可以設定預設的 login module 和 action
all:
.actions:
login_module: default
login_action: login
secure_module: default
secure_action: secure
簡易的登入登出會是像這樣子
class myAccountActions extends sfActions
{
public function executeLogin()
{
if ($this->getRequestParameter('login') == 'foobar')
{
$this->getUser()->setAuthenticated(true);
}
}
public function executeLogout()
{
if ($this->getUser()->isAuthenticated())
{
$this->getUser()->setAuthenticated(false);
}
}
}
然後有關 Credential 的 Demo:
class myAccountActions extends sfActions
{
public function executeDoThingsWithCredentials()
{
$user = $this->getUser();
// Add one or more credentials
$user->addCredential('foo');
$user->addCredentials('foo', 'bar');
// Check if the user has a credential
echo $user->hasCredential('foo'); => true
// Check if the user has both credentials
echo $user->hasCredential(array('foo', 'bar')); => true
// Check if the user has one of the credentials
echo $user->hasCredential(array('foo', 'bar'), false); => true
// Remove a credential
$user->removeCredential('foo');
echo $user->hasCredential('foo'); => false
// Remove all credentials (useful in the logout process)
$user->clearCredentials();
echo $user->hasCredential('bar'); => false
}
}
最後是在 template 裡面要知道 credential 也是透過 $sf_user 這個看過才知道的物件。
<ul>
<li><?php echo link_to('section1', 'content/section1') ?></li>
<li><?php echo link_to('section2', 'content/section2') ?></li>
<?php if ($sf_user->hasCredential('section3')): ?>
<li><?php echo link_to('section3', 'content/section3') ?></li>
<?php endif; ?>
</ul>
Read more |
No Comments » |
May 26th, 2008
Posted in Symfony | By tarotoast | Tags: code, cookie, note, php, session, symfony
Symfony 裡面的 Session 是透過 sfUser 這個 class 來完成的,可以在 action 裡面透過 $this->getUser() 來取得。關於 cookie 本身的設定則是在 apps/myapp/config/factories.yml 下面。Session 的存活時間 (timeout) 則是在 apps/myapp/config/settings.yml 裡面。
class mymoduleActions extends sfActions
{
public function executeFirstPage()
{
$nickname = $this->getRequestParameter('nickname');
// Store data in the user session
$this->getUser()->setAttribute('nickname', $nickname);
}
public function executeSecondPage()
{
// Retrieve data from the user session with a default value
$nickname = $this->getUser()->getAttribute('nickname', 'Anonymous Coward');
}
}
除掉 Session 裡面的資料:
class mymoduleActions extends sfActions
{
public function executeRemoveNickname()
{
$this->getUser()->getAttributeHolder()->remove('nickname');
}
public function executeCleanup()
{
$this->getUser()->getAttributeHolder()->clear();
}
}
然後在 Template 裡面則是用 $sf_use 這個預設的物件來存取,沒看 documentation 鬼才知道。
<p>
Hello, <?php echo $sf_user->getAttribute('nickname') ?>
</p>
Read more |
No Comments » |
May 26th, 2008
Posted in Symfony | By tarotoast | Tags: code, note, php, symfony, upload
看到這段 Code 的時候真是有種喔原來有這些喔的感覺,趕快記錄下來。這些都是在 Action 裡面可以用的 method,重點是沒有查 API 誰會知道有這些可以用。[sfActions API]
class mymoduleActions extends sfActions
{
public function executeIndex()
{
// Retrieving request parameters
$password = $this->getRequestParameter('password');
// Retrieving controller information
$moduleName = $this->getModuleName();
$actionName = $this->getActionName();
// Retrieving framework core objects
$request = $this->getRequest();
$userSession = $this->getUser(); // 這個最不像
$response = $this->getResponse();
$controller = $this->getController();
$context = $this->getContext();
// Setting action variables to pass information to the template
$this->setVar('foo', 'bar');
$this->foo = 'bar'; // Shorter version
}
}
以上的 $this 如果在 Template 裡面要呼叫的話,記得使用 $sf_context 這個物件。
sfActions 的不同用法:
class mymoduleActions extends sfActions
{
public function preExecute()
{
// The code inserted here is executed at the beginning of each action call
...
}
public function executeIndex()
{
...
}
public function executeList()
{
...
$this->myCustomMethod(); // Methods of the action class are accessible
}
public function postExecute()
{
// The code inserted here is executed at the end of each action call
...
}
protected function myCustomMethod()
{
// You can also add your own methods, as long as they don't start with "execute"
// In that case, it's better to declare them as protected or private
...
}
}
File Upload 在 Symfony 下面非常簡單就解決,想想看如果指有用 php 寫處理個檔案上傳要寫幾行?
class mymoduleActions extends sfActions
{
public function executeUpload()
{
if ($this->getRequest()->hasFiles())
{
foreach ($this->getRequest()->getFileNames() as $fileName)
{
$fileSize = $this->getRequest()->getFileSize($fileName);
$fileType = $this->getRequest()->getFileType($fileName);
$fileError = $this->getRequest()->hasFileError($fileName);
$uploadDir = sfConfig::get('sf_upload_dir');
$this->getRequest()->moveFile('file', $uploadDir.'/'.$fileName);
}
}
}
}
Read more |
No Comments » |
May 26th, 2008
Recent Comments