教程:如何使用CodeIgniter来更新Twitter
这是一篇原创译文,转载请注明出处。
原文作者Drazen Mokic,你可以在 这里 看到原文。
在这个教程里面我们将使用CodeIgniter,通过Twitter API来更新我们的twitter状态。我建议大家一步一步的学习,而不要走马观花式的浏览教程。让我们开始深入学习吧!
教程细节
程序:CodeIgniter框架
版本:1.7.1
难度:高级
预计完成时间:30分钟
1.配置CodeIgniter
首先我们需要对CI的默认配置进行修改。打开 system/application/config/autoload.php 文件,找到下面这行
$autoload['libraries'] = array('');
修改为
$autoload['libraries'] = array('database');
这样就可以自动加载数据库了。接下来,打开 database.php 并修改其中的数据库连接设置-你的数据库名、用户名以及密码。我们使用的名称是 ci_twitter_api。
现在打开 config.php,并修改 base_url 为你的CI目录路径。我使用的目录叫做 twitter_api,我的 system目录就保存在那个位置,因此我的 base_url 会是
$config['base_url'] = "http://localhost/ci/twitter_api";
2.填充数据库
因为我们将要用到数据库,所以我们需要填充一些数据。打开 phpMyAdmin 或者其它你喜欢的数据库管理工具,创建一个新的数据库,命名为 ci_twitter_api。现在我们将要使用下面的SQL查询语句来创建一个表,但请注意,使用你自己的twitter用户名和密码。
1 2 3 4 5 6 7 8 9 10 11 | CREATE TABLE IF NOT EXISTS `accounts` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(120) NOT NULL, `password` varchar(32) NOT NULL, `active` int(11) NOT NULL, `last_message` varchar(140) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ; INSERT INTO `accounts` (`id`, `username`, `password`, `active`, `last_message`) VALUES (1, '<strong>YOUR USERNAME</strong>', '<strong>YOUR PASSWORD</strong>', 1, 'No message sent.'); |

图1
单击右边的 OK 按钮,查询就会被提交。现在你的accounts表的结构应该和下图是类似的:

图2
3.构建模型
转到 system/application/models 下面,新建一个文件并命名为 twitter_model.php。
首先,我们在顶部声明两个全局变量。
1 2 | var $accounts_table = 'accounts'; var $update_url = 'http://twitter.com/statuses/update.xml'; |
因此,$accounts_table 对应的是我们之前所创建的表,$update_url 则是我们用来更新状态的URL。如果Twitter更改了它的更新URL,你只需要修改一次就可以了,不必每次都修改。
现在我们将要创建第一个方法,作用是返回数据库中存储的活跃用户帐户,依据是active字段及其值1。我添加了这一项是因为可能有些人拥有多个twitter账户。
1 2 3 4 5 6 7 | class Twitter_model extends Model { // get the active twitter account from the database, by row active = 1 function getActiveAccount() { return $this->db->get_where($this->accounts_table, array('active' => '1'))->row(); } |
我们简单的使用 ActiveRecord 来检索活跃的账户并返回受影响的行。
下一步,我们将要构建主要方法,也就是 update 方法。它将要用到我们的用户名、密码以及我们想要在Twitter上更新的消息。除此之外,它还将对Twitter所返回的 HTTP_CODE 进行解析,以便告诉我们更新是否成功。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | // update twitter status and last message on success function update_status($username, $password, $message) { $ch = curl_init($this->update_url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, 'status='.urlencode($message)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_USERPWD, $username . ':' . $password); curl_exec($ch); $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); // if we were successfull we need to update our last_message if ($httpcode == '200') { $this->db->where('active', '1'); $this->db->update($this->accounts_table, array('last_message' => $message)); return TRUE; } else { return FALSE; } } |
乍一看去这段代码有点复杂,但并不是很难理解的。最重要的一点是,我们使用了 cURL 和Twitter进行通信。cURL是一个非常优秀的库,允许我们通过它来发送和接收来自Twitter的HTTP POST数据。
那么,curl_init 初始化一个cURL会话并将URL作为参数接受-在我们这个案例中就是Twitter API所提供的更新URL。
我们通过 curl_setopt 设置了一些选项,这些对于 cURL传输来说是必不可少的。
- CURLOPT_POST: 此项设置为’1′,表示我们将使用 HTTP POST,这与HTML表单中是一样的。
CURLOPT_POSTFIELDS: 此项接收的是我们想要发送的 POST 数据。在本案例中是 ’status=’ 和我们要发送的消息。我们需要对消息进行 urlencode ,以便使用 ‘%&/” 这类的特殊字符。
CURLOPT_RETURNTRANSFER: 将此项设置为’1′是非常重要的,因为它将把传输作为字符串返回。这一字符串将告诉我们更新是否成功。
CURLOPT_USERPWD: 此项的作用是身份验证。它只是以 用户名:密码 这种格式包含我们的twitter帐户信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | curl_exec($ch); $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); // if we were successfull we need to update our last_message if ($httpcode == '200') { $this->db->where('active', '1'); $this->db->update($this->accounts_table, array('last_message' => $message)); return TRUE; } else { return FALSE; } |
在这一部分我们通过 curl_exec() 执行传输并且使用 curl_getinfo(CURLINFO_HTTP_CODE) 来检索返回的HTTP_CODE。这里的HTTP_CODE将告诉我们更新是否成功。代码’200′表示更新成功。你可以在 这里 查看到一份完整的HTTP状态代码列表。
如果我们收到了Twitter所返回的’200′,我们将向数据库发出一条查询语句,用来更新last_message字段,最后我们返回TRUE。如果Twitter没有返回200,我们简单的返回FALSE。
为了完成我们的 twitter_model,我们还将创建最后一个方法,作用是获取我们最后发送的信息。我们之所以需要这个方法是因为我们要在视图中显示最近发送的信息。
1 2 3 4 5 6 7 8 | // get the last_message, by row active = 1 function getLastMessage() { $this->db->select('last_message'); $last_message = $this->db->get_where($this->accounts_table, array('active' => '1'))->row()->last_message; return htmlspecialchars($last_message); } |
这个方法很简单。它从我们的活跃帐户所对应的last_message字段检索信息,并经过 htmlspecialchars 转换成HTML实体返回。我们的 twitter_model.php 看起来像这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | class Twitter_model extends Model { var $accounts_table = 'accounts'; var $update_url = 'http://twitter.com/statuses/update.xml'; // get the active twitter account from the database, by row active = 1 function getActiveAccount() { return $this->db->get_where($this->accounts_table, array('active' => '1'))->row(); } // update twitter status and last message on success function update_status($username, $password, $message) { $ch = curl_init($this->update_url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, 'status='.urlencode($message)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_USERPWD, $username . ':' . $password); curl_exec($ch); $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); // if we were successfull we need to update our last_message if ($httpcode == '200') { $this->db->where('active', '1'); $this->db->update($this->accounts_table, array('last_message' => $message)); return TRUE; } else { return FALSE; } } // get the last_message, by row active = 1 function getLastMessage() { $this->db->select('last_message'); $last_message = $this->db->get_where($this->accounts_table, array('active' => '1'))->row()->last_message; return htmlspecialchars($last_message); } } |
4.构建控制器
现在转到 system/application/controllers,新建一个文件,命名为 twitter.php。让我们添加几行:
1 2 3 4 5 6 7 8 | class Twitter extends Controller { function Twitter() { parent::Controller(); $this->load->model('twitter_model'); } |
这是一个简单的CI构造函数,加载我们的 twitter_model。因此整个控制器都是可用的。下面是 index() 方法。
1 2 3 4 5 6 7 8 9 10 | function index() { $data['heading'] = 'Hi, send a tweet!'; $data['last_message'] = $this->twitter_model->getLastMessage(); $data['active_user'] = $this->twitter_model->getActiveAccount()->username; $this->load->view('header', $data); $this->load->view('index'); $this->load->view('footer'); } |
我们将文本、最近的消息、活跃帐户的用户名等信息传递给 $data 数组。获取最近的消息以及活跃的用户名变得轻而易举,这应该归功于我们的 twitter_model。最后我们加载一些视图(编写完控制器后就会创建它们)。让我们来构建 update 方法吧。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | // updating our status on twitter ( new message ) function update() { if ($this->input->post('submit')) { $this->load->library('form_validation'); $this->form_validation->set_error_delimiters('<div class="error">', '</div>'); $this->form_validation->set_rules('message', 'Message', 'trim|required|min_length[5]|max_length[140]'); if ($this->form_validation->run() == FALSE) { $this->index(); } else { $message = $this->input->post('message'); // get useraccount data $account = $this->twitter_model->getActiveAccount(); $username = $account->username; $password = $account->password; // send a tweet if ($this->twitter_model->update_status($username, $password, $message)) { redirect('twitter'); } else { $data['error'] = 'There was an error while updating your status'; $this->load->view('header', $data); $this->load->view('error'); $this->load->view('footer'); } } } |
这可能又会使你感到迷惑,但我们还是逐步的完成它。
1 2 3 4 5 6 7 8 9 10 11 12 | if ($this->input->post('submit')) { $this->load->library('form_validation'); $this->form_validation->set_error_delimiters(' <div class="error">', '</div> '); $this->form_validation->set_rules('message', 'Message', 'trim|required|min_length[5]|max_length[140]'); if ($this->form_validation->run() == FALSE) { $this->index(); } |
我们通过 $this->input->post(’submit’) 检查表单(稍后我们会在主要的视图文件中创建它)是否已被提交。然后,我们加载表单验证类,因为我们希望使用某些输入规则,比如最短5个字符、最多140个字符。此外我们还使用 trim 来过滤掉空格,并将此字段设置为 required(必需),因为我们不需要空的消息。set_rules函数的第一个参数是表单字段的名称,在本案例中是 message (稍后我们会在视图中创建它),第二个参数则是此表单字段的“人性化”的名称,它将被插入到错误信息中(将在视图文件中完成)。
我们调用 $this->form_validation->run() ,此方法返回 TRUE 或者 FALSE。如果我们所设置的某条规则被破坏,它将返回 FALSE 并且调用我们的 index() 方法。而 index() 方法所调用的视图中就会显示错误信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | else { $message = $this->input->post('message'); // get useraccount data $account = $this->twitter_model->getActiveAccount(); $username = $account->username; $password = $account->password; // send a tweet if ($this->twitter_model->update_status($username, $password, $message)) { redirect('twitter'); } else { $data['error'] = 'There was an error while updating your status'; $this->load->view('header', $data); $this->load->view('error'); $this->load->view('footer'); } } |
再次感谢我们的 twitter_model,检索当前的用户名和密码变得轻而易举。当然我们也可以使用 $username = $this->twitter_model->getActiveAccount()->username ,但我觉得对这段教程来说这就更好理解一些。
通过 $this->twitter_model->update_status() 我们调用那个与Twitter进行“通话”的方法。它把我们的用户名、密码以及我们要发送的消息告诉Twitter。如果状态更新成功,我们就会调用URL辅助函数中的 redirect() 进行重定向。
如果出了错,我们设置一条错误消息并加载几个视图文件(下一步会创建它们)。现在控制器看上去是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | class Twitter extends Controller { function Twitter() { parent::Controller(); $this->load->model('twitter_model'); } function index() { $data['heading'] = 'Hi, send a tweet!'; $data['last_message'] = $this->twitter_model->getLastMessage(); $data['active_user'] = $this->twitter_model->getActiveAccount()->username; $this->load->view('header', $data); $this->load->view('index'); $this->load->view('footer'); } // updating our status on twitter ( new message ) function update() { if ($this->input->post('submit')) { $this->load->library('form_validation'); $this->form_validation->set_error_delimiters(' <div class="error">', '</div> '); $this->form_validation->set_rules('message', 'Message', 'trim|required|min_length[5]|max_length[140]'); if ($this->form_validation->run() == FALSE) { $this->index(); } else { $message = $this->input->post('message'); // get useraccount data $account = $this->twitter_model->getActiveAccount(); $username = $account->username; $password = $account->password; // send a tweet if ($this->twitter_model->update_status($username, $password, $message)) { redirect('twitter'); } else { $data['error'] = 'There was an error while updating your status'; $this->load->view('header', $data); $this->load->view('error'); $this->load->view('footer'); } } } else { redirect('twitter'); } } |
5.创建视图
现在我们就要创建视图文件了。转到 system/application/views 下面,创建如下几个文件:
header.php
footer.php
index.php
error.php
header.php将包含基本的HTML元信息、我们的CSS链接以及主要的div(如#wrapper 和 #main)开启标签。
1 2 3 4 5 6 7 8 9 10 11 12 13 | < !DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <link media="screen" rel="Stylesheet" type="text/css" href="<?php echo base_url(); ?>css/style.css" /> <title>Using the Twitter API with CodeIgniter</title> </link></head> <body> <div id="wrapper"> <div id="main"> |
我们使用 base_url() 来引用我们的CSS文件(下一步会创建它)。
footer.php只是包含了我们的关闭标签。
</div><!--end main-->
</div><!--end wrapper--></body></html>index.php才是最重要的部分。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <h3> < ?php echo $heading; ?> ( account: < ?php echo anchor('http://twitter.com/' . $active_user, $active_user); ?> )</h3> < ?php echo form_error('message'); ?> < ?php echo form_open('twitter/update', array('id' => 'update_form')); ?> < ?php echo form_input(array('name' => 'message', 'maxlength' => '140')); ?> < ?php echo form_submit('submit', 'update'); ?> < ?php echo form_close(); ?> <div id="last_message"> <fieldset> <legend>Last sent by <strong>< ?php echo $active_user ?></strong></legend> < ?php echo $last_message; ?> </fieldset></div> <!--end last_message--> |
这里用到的所有变量都是通过我们的控制器中的 index() 方法传递的。除此之外,我们还使用了表单辅助函数来创建一个简单的HTML表单。记住,我告诉过你,这里是进行错误处理的地方;form_error(‘message’) 就是完成这一工作的魔法师。
在表单下面,显示的是当前活跃用户所发送的最后一则消息。
最后,error.php作为一个自定义的错误文件,万一出现更新不成功的情况就可以用得上。
1 2 | <h3>< ?php echo $error; ?></h3> < ?php echo anchor('twitter', 'Go back and try again'); ?> |
6.添加一些CSS
为了使页面更加美观,我们将添加一些CSS。转到 system/ 下面并创建 css目录。在那个目录下创建一个 style.css 文件,然后输入如下的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | /* Reset CSS */ html, body, div, span, object, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, address, code, img, small, strong, dl, dt, dd, ol, ul, li, fieldset, form, label { margin: 0; padding: 0; border: 0; outline: 0; font-size: 100%; vertical-align: baselinebaseline; background: transparent; } body { line-height: 1.5; font-family:Arial, sans-serif; margin:0; } ol, ul, li { list-style: none; list-style-type:none; } .clear { clear:both; } /* DEFAULTS */ h3 { color:#35CCFF; font-size:20px; } /* CUSTOM */ #wrapper { width:900px; margin:0 auto; } /* main */ #main { margin-top:50px; } #main h3 span { font-size:14px; color:#cccccc; } #main h3 a { color:#cccccc; } /* form */ #update_form input { width:888px; padding:5px; border:1px solid #d3d3d3; display:block; } #update_form input[type="submit"] { width:auto; margin-top:10px; background-color:#000000;; border:none; color:white; font-size:12px; font-weight:bold; cursor:pointer; padding:3px; } div.error { display:block; background-color:#FB8A8A; border:1px solid #FF3B3B; padding:5px; color:#ffffff; width:50%; margin-bottom:30px; font-weight:bold; margin:0 auto 10px auto; text-align:center; } /* last message */ #last_message fieldset { border:1px dashed #d3d3d3; padding:5px; margin-top:30px; } #last_message fieldset p { padding:5px; font-size:18px; font-weight:normal; } #last_message legend span { font-size:12px; } |
我使用了 Eric Meyers 的CSS重置方法,这样可以消除不同浏览器之间的差异。你的应用程序看上去应该像下图这样。

图3
大结局
现在让我们来测试一下新编写的应用程序。我们将输入一条信息并单击 update 按钮!

图4
更新完成后就会显示:

图5
让我们看看Twitter:)

图6
如果我们试图发送一则空消息,破坏了表单验证规则:

图7
结论
我真心希望这对你学习CodeIgniter和如何使用优秀的Twitter API有所帮助!你遇到难题了么? 如果有,请告诉我们!
由于众所周知的某原因,如果不使用代理,我们无法在国内访问到Twitter主站,甚至包括其API。这样的话如果使用Twitter官方的API就会导致更新失败。没有关系,我们可以使用第三方的API来完成这个工作。 修改为 这样就可以了。下面是我的测试结果: 我的测试结果1
译者后记
打开 twitter_model.php ,找到这一行:var $update_url = 'http://twitter.com/statuses/update.xml';
var $update_url = 'http://nest.onedd.net/api/statuses/update.xml';
下面是Twitter主站上看到的结果:
Twitter主站上的测试结果


