2007年12月9日星期日

asdasd

asdasdasdasd

这边风景独烂

感觉很不好啊,这些天过的很迷茫,虽然我有在为我的个人主页工作,但是找不到动力,一是因为我自己觉得没有好的想法,陷入了一种细节当中,但是这些很有可能是后面需要改动的,我采用的自底而上的开发方法似乎有点问题,我连网站需要些什么都不是很明确,虽然我确定了开发方向,但是始终是没有动力,找不到突破点,我想自己找一个需要的点子去做一些东西。就做ROR的吧,一是可以学习很多的东西,二是要让自己完完整整的做点东西吧,没有实践是不行的。

这边风景独烂

感觉很不好啊,这些天过的很迷茫,虽然我有在为我的个人主页工作,但是找不到动力,一是因为我自己觉得没有好的想法,陷入了一种细节当中,但是这些很有可能是后面需要改动的,我采用的自底而上的开发方法似乎有点问题,我连网站需要些什么都不是很明确,虽然我确定了开发方向,但是始终是没有动力,找不到突破点,我想自己找一个需要的点子去做一些东西。就做ROR的吧,一是可以学习很多的东西,二是要让自己完完整整的做点东西吧,没有实践是不行的。

zendframework之我见

asdf

杨晶,你为什么会让我如此的痴迷?

真的说不上为什么,就是喜欢你,不过对自己也很无语,没有一点的勇气。。

2007年12月8日星期六

askeet 10

symfony advent calendar day seventeen: API



Previously on symfony



The askeet application was just put online yesterday, and we already have a lot of feedback about feature tweaking and additions. The user input is fundamental to the design of a web 2.0 application, and even if the concept of the application is new, it has to be experimented with as soon as possible.



But we will add unplanned functionalities on day 21. Before that, we have scheduled a handful of advanced web application development techniques to show you through askeet, and the first to be revealed today is the programming of an external API requiring an HTTP authentication.



As we made quite a lot of little changes yesterday, you are strongly advised to start today's tutorial with a fresh downloaded version of askeet from the day 16 tagged version in the askeet repository.



The API



An Application Programming Interface, or API, is a developer's interface to a particular service on your application, so that it can be included in external websites. Think about Google Maps or Flickr, which are used to extend lots of websites over the Internet thanks to their APIs.



Askeet makes no exception, and we believe that in order to increase the service's popularity, it has to be made available to other websites. The RSS feed developed during day 11 was a first approach to that requirement, but we can do much better.



Askeet will provide an API of answers to a question asked by the user. The access to this API will be restricted to registered askeet users, through HTTP authentication. The API response format chosen is Representational State Transfer, or REST - that means that the response is a simple XML block similar to most of the output of main APIs in the web:



[xml]
<?xml version="1.0" encoding="utf-8" ?>
<rsp stat="ok" version="1.0">
<question href="http://www.askeet.com/question/what-shall-i-do-tonight-with-my-girlfriend" time="2005-11-21T21:19:18Z" >
<title>What shall I do tonight with my girlfriend?</title>
<tags>
<tag>activities</tag>
<tag>relatives</tag>
<tag>girl</tag>
<tags>
<answers>
<answer relevancy="50" time="2005-11-22T12:21:53Z">You can try to read her poetry. Chicks love that kind of things.</answer>
<answer relevancy="0" time="2005-11-22T15:45:03Z">Don't bring her to a doughnuts shop. Ever. Girls don't like to be seen eating with their fingers - although it's nice.</answer>
</answers>
</question>
</rsp>


We will implement the API in a new module of the frontend application, so use the command line to build the module skeleton:



$ symfony init-module frontend api


HTTP Authentication



We choose to limit the use of the API to registered askeet users. For that, we will use the HTTP authentication process, which is a built-in authentication mechanism of the HTTP protocol. It is different from the web authentication that we have seen previously because it doesn't even require a web page - all the exchanges take place in the HTTP headers.



We will need the authentication method included in a custom validator during day six, so first of all we will do some refactoring and relocate the login code in the UserPeer model class:



[php]
public static function getAuthenticatedUser($login, $password)
{
$c = new Criteria();
$c->add(UserPeer::NICKNAME, $login);
$user = UserPeer::doSelectOne($c);

// nickname exists?
if ($user)
{
// password is OK?
if (sha1($user->getSalt().$password) == $user->getSha1Password())
{
return $user;
}
}

return null;
}


The new class method UserPeer::getAutenticatedUser() can now be used in the myLoginValidator.class.php (we'll leave that to you) and in the new api/index web service:



[php]
<?php

class apiActions extends sfActions
{
public function preExecute()
{
sfConfig::set('sf_web_debug', false);
}

public function executeIndex()
{
$user = $this->authenticateUser();
if (!$user)
{
$this->error_code = 1;
$this->error_message = 'login failed';

$this->forward('api', 'error');
}
// do some stuff
}

private function authenticateUser()
{
if (isset($_SERVER['PHP_AUTH_USER']))
{
if ($user = UserPeer::getAuthenticatedUser($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']))
{
$this->getContext()->getUser()->signIn($user);

return $user;
}
}

header('WWW-Authenticate: Basic realm="askeet API"');
header('HTTP/1.0 401 Unauthorized');
}

public function executeError()
{
}
}

?>


askeet 10

symfony advent calendar day seventeen: API



Previously on symfony



The askeet application was just put online yesterday, and we already have a lot of feedback about feature tweaking and additions. The user input is fundamental to the design of a web 2.0 application, and even if the concept of the application is new, it has to be experimented with as soon as possible.



But we will add unplanned functionalities on day 21. Before that, we have scheduled a handful of advanced web application development techniques to show you through askeet, and the first to be revealed today is the programming of an external API requiring an HTTP authentication.



As we made quite a lot of little changes yesterday, you are strongly advised to start today's tutorial with a fresh downloaded version of askeet from the day 16 tagged version in the askeet repository.



The API



An Application Programming Interface, or API, is a developer's interface to a particular service on your application, so that it can be included in external websites. Think about Google Maps or Flickr, which are used to extend lots of websites over the Internet thanks to their APIs.



Askeet makes no exception, and we believe that in order to increase the service's popularity, it has to be made available to other websites. The RSS feed developed during day 11 was a first approach to that requirement, but we can do much better.



Askeet will provide an API of answers to a question asked by the user. The access to this API will be restricted to registered askeet users, through HTTP authentication. The API response format chosen is Representational State Transfer, or REST - that means that the response is a simple XML block similar to most of the output of main APIs in the web:



[xml]
<?xml version="1.0" encoding="utf-8" ?>
<rsp stat="ok" version="1.0">
<question href="http://www.askeet.com/question/what-shall-i-do-tonight-with-my-girlfriend" time="2005-11-21T21:19:18Z" >
<title>What shall I do tonight with my girlfriend?</title>
<tags>
<tag>activities</tag>
<tag>relatives</tag>
<tag>girl</tag>
<tags>
<answers>
<answer relevancy="50" time="2005-11-22T12:21:53Z">You can try to read her poetry. Chicks love that kind of things.</answer>
<answer relevancy="0" time="2005-11-22T15:45:03Z">Don't bring her to a doughnuts shop. Ever. Girls don't like to be seen eating with their fingers - although it's nice.</answer>
</answers>
</question>
</rsp>


We will implement the API in a new module of the frontend application, so use the command line to build the module skeleton:



$ symfony init-module frontend api


HTTP Authentication



We choose to limit the use of the API to registered askeet users. For that, we will use the HTTP authentication process, which is a built-in authentication mechanism of the HTTP protocol. It is different from the web authentication that we have seen previously because it doesn't even require a web page - all the exchanges take place in the HTTP headers.



We will need the authentication method included in a custom validator during day six, so first of all we will do some refactoring and relocate the login code in the UserPeer model class:



[php]
public static function getAuthenticatedUser($login, $password)
{
$c = new Criteria();
$c->add(UserPeer::NICKNAME, $login);
$user = UserPeer::doSelectOne($c);

// nickname exists?
if ($user)
{
// password is OK?
if (sha1($user->getSalt().$password) == $user->getSha1Password())
{
return $user;
}
}

return null;
}


The new class method UserPeer::getAutenticatedUser() can now be used in the myLoginValidator.class.php (we'll leave that to you) and in the new api/index web service:



[php]
<?php

class apiActions extends sfActions
{
public function preExecute()
{
sfConfig::set('sf_web_debug', false);
}

public function executeIndex()
{
$user = $this->authenticateUser();
if (!$user)
{
$this->error_code = 1;
$this->error_message = 'login failed';

$this->forward('api', 'error');
}
// do some stuff
}

private function authenticateUser()
{
if (isset($_SERVER['PHP_AUTH_USER']))
{
if ($user = UserPeer::getAuthenticatedUser($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']))
{
$this->getContext()->getUser()->signIn($user);

return $user;
}
}

header('WWW-Authenticate: Basic realm="askeet API"');
header('HTTP/1.0 401 Unauthorized');
}

public function executeError()
{
}
}

?>