Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
實戰 Fight with CodeIgniter
Search
Bo-Yi Wu
September 29, 2014
Technology
0
97
實戰 Fight with CodeIgniter
成功大學電算中心教育訓練
Bo-Yi Wu
September 29, 2014
Tweet
Share
More Decks by Bo-Yi Wu
See All by Bo-Yi Wu
如何設計一套具備 Container 容器化技術的 CI/CD 平台?
appleboy
0
1k
生成式 AI CodeGPT 開發經驗談
appleboy
0
2.7k
打造 MLOps 平台 改善 AI 模型開發流程
appleboy
0
2k
自動化監控伺服器工具 - Gatus
appleboy
0
3.7k
Drone CI/CD 自動化測試及部署
appleboy
1
450
初探 Infrastructure as Code 工具 Pulumi
appleboy
2
3.4k
Introduction to Open Policy Agent
appleboy
0
1.8k
善用 Go 語言效能測試工具來提升執行效率
appleboy
2
4.3k
用 Go 語言打造多台機器 Scale 架構
appleboy
1
4.5k
Other Decks in Technology
See All in Technology
隣接領域をBeyondするFinatextのエンジニア組織設計 / beyond-engineering-areas
stajima
1
270
Taming you application's environments
salaboy
0
180
OCI Network Firewall 概要
oracle4engineer
PRO
0
4.1k
OCI 運用監視サービス 概要
oracle4engineer
PRO
0
4.8k
障害対応指揮の意思決定と情報共有における価値観 / Waroom Meetup #2
arthur1
5
470
マルチプロダクトな開発組織で 「開発生産性」に向き合うために試みたこと / Improving Multi-Product Dev Productivity
sugamasao
1
300
Terraform Stacks入門 #HashiTalks
msato
0
350
TanStack Routerに移行するのかい しないのかい、どっちなんだい! / Are you going to migrate to TanStack Router or not? Which one is it?
kaminashi
0
580
Lambdaと地方とコミュニティ
miu_crescent
2
370
オープンソースAIとは何か? --「オープンソースAIの定義 v1.0」詳細解説
shujisado
7
800
New Relicを活用したSREの最初のステップ / NRUG OKINAWA VOL.3
isaoshimizu
2
590
TypeScriptの次なる大進化なるか!? 条件型を返り値とする関数の型推論
uhyo
2
1.6k
Featured
See All Featured
Imperfection Machines: The Place of Print at Facebook
scottboms
265
13k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
38
1.8k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
665
120k
Optimizing for Happiness
mojombo
376
70k
Building Your Own Lightsaber
phodgson
103
6.1k
The World Runs on Bad Software
bkeepers
PRO
65
11k
Code Reviewing Like a Champion
maltzj
520
39k
Adopting Sorbet at Scale
ufuk
73
9.1k
Navigating Team Friction
lara
183
14k
Thoughts on Productivity
jonyablonski
67
4.3k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
42
9.2k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
Transcript
1 實戰 CodeIgniter PHP Framework Bo-Yi Wu (appleboy) 2014.09.26 成功大學電算中心
2 關於我 Bo-Yi Wu (appleboy) – Blog: http://blog.wu-boy.com/ – Github:
https://github.com/appleboy – CodeIgniter 站長 – Laravel 站長
3 為什麼要使用 Framework Why should I use a framework ?
4 不用重新造輪子 Not having to reinvent the wheel
5 容易升級與維護 upgradability and maintenance
6 既定開發流程 Develop Flow
7 網站安全性 Web Security
8 網站安全性 • 管理介面 URL • 目錄 (Index of) •
錯誤訊息 • 暫存測試資訊 • 版本控管 • SQL Injection
9 Joomla 管理介面
10 早期 phpMyAdmin 有漏洞風險
11 常用管理介面路徑 • /admin/ • /phpMyAdmin/ • /adminLogin/ • /manage/
• /management/ • /root/ • /wp-admin/ 政府機關、學校機構、電信業者
12 如何防禦 • 限制存取 IP(Apache, Nginx) • 隱藏管理介面 ( 複雜目錄名稱
) • 增加後台防禦 (Captcha …)
13 網站安全性 • 管理介面 URL • 目錄 (Index of) •
錯誤訊息 • 暫存測試資訊 • 版本控管 • SQL Injection
14
15 Index of • 網路目錄結構曝光 • 存取敏感檔案 – .bak –
config.php.bak – .svn, .git, – database.yml
16 如何防禦 關閉 Index 功能 (Apache) <Directory /> Options -Indexes
</Directory>
17 網站安全性 • 管理介面 URL • 目錄 (Index of) •
錯誤訊息 • 暫存測試資訊 • 版本控管 • SQL Injection
18 SQL 錯誤訊息
19 如何防禦 • 關閉錯誤顯示 – php.ini – display_errors = off
• 使用 Framework 都可以直接設定在專案裡
20 網站安全性 • 管理介面 URL • 目錄 (Index of) •
錯誤訊息 • 暫存測試資訊 • 版本控管 • SQL Injection
21 暫存測試資訊 • 開發者求方便使用檔名備份 – .bak, xxx.php2 • 編輯器自動備份 –
index.php~, index.php.swp • 看系統資訊 – phpinfo.php
22 不要在 Production 機器上 改程式碼 set vim :set nobackup
23 如何防禦 • 不要在正式產品環境中進行開發 • 關閉編輯器自動備份 • 伺服器過濾檔案下載 – Nginx
# Prevent clients from accessing to backup/config/source files location ~* (?:\.(?:bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist)|~)$ { deny all; }
24 網站安全性 • 管理介面 URL • 目錄 (Index of) •
錯誤訊息 • 暫存測試資訊 • 版本控管 • SQL Injection
25 版本控管 http://xxxx.com/.git/config http://xxxx.com/.git http://xxxx.com/.svn
26
27 如何防禦 • 開發環境跟正式環境切開 • 禁止版本控制資料夾存取 • 導入 Deploy 流程
(Continuous Integration)
28 網站安全性 • 管理介面 URL • 目錄 (Index of) •
錯誤訊息 • 暫存測試資訊 • 版本控管 • SQL Injection
29 SQL Injection SELECT id FROM users WHERE email =
‘$email‘ and password = ‘$password’; SELECT id FROM users WHERE email = ‘$email‘ and password = ‘anything' OR ‘1’ = ‘1’;
30 如何防禦 • 請不要相信使用者任何輸入字串 • 正規比對格式 – preg_match(‘/^(\w)+$/’, $string); –
使用 framework 提供 escape 函式 • 型態轉換 Typecasting
31 型態轉換 Typecasting $var = (array) $var; $var = (binary)
$var; $var = (bool) $var; $var = (boolean) $var; $var = (double) $var; $var = (float) $var; $var = (int) $var; $var = (integer) $var; $var = (object) $var; $var = (real) $var; $var = (string) $var;
32 選擇 PHP Framework
33
34
35 為什麼要選擇 CodeIgniter • 安裝容易 • 輕易上手 • 繁中文件
36 安裝容易 wget + unzip = done
37 輕易上手 只要會一點點物件導向即可
38 繁中文件 目前只有 CodeIgniter 、 Laravel 有繁中文件 http://codeigniter.org.tw/user_guide/ http://bit.ly/ci-userguide
39 CodeIgniter3.0 發展 目前最新為 2.2.0 版本
40 EllisLab Seeking New Owner for CodeIgniter http://bit.ly/ci-seek-new-owner
41
42 3.0 版本有超過 100 個 bug fixed 100 個 feature
commit http://bit.ly/ci-changelog
43 CodeIgniter 架構
44 CodeIgniter 架構 • application 開發 MVC 程式碼 • system
系統程式碼 • user_guide 線上文件 • index.php 主檔案
45 index.php • $application_folder = 'application'; • $system_path = 'system';
46 更動 Web 架構
47 CodeIgniter 架構 • application • system • public/index.php •
public/robots.txt • Public/.htaccess
48 index.php • $application_folder = ‘../application'; • $system_path = ‘../system';
49 使用者無法存取 index.php 以外的檔案 Apache: DocumentRoot /xxx/public Nginx: root /xxx/public
50 隱藏 URL index.php 字串
51 Apache RewriteEngine on RewriteBase / RewriteCond $1 !^(index\.php|robots\.txt|$) RewriteRule
^(.*)$ index.php/$1 [L,QSA]
52 Nginx location / { try_files $uri $uri/ /index.php?$query_string; }
53 使用此架構好處 • 避免 .git 曝露 • 根目錄可以放其他設定檔 – .editorconfig
– .gitignore – gulpfile.coffee – bower.js – package.json
54 作業一 • 建立一個 virtual host: ci.localhost • 安裝 codeigniter
2.2.0 • 移除 url 的 index.php 字串 – http://ci.localhost/welcome
55 CodeIgniter 核心架構
56 核心架構 • core – Controller, Model, Router, Loader, Input
… • database – MySQL, ODBC, MSSQL, Sqlite … • helpers – email, url, text, number, language … • language – zh-tw, zh-cn, english … • libraries – Form, Image, Session, Email, Pagination
57 核心函式不夠用 擴充核心函式庫
58 擴充核心函式庫 • core – MY_Model, MY_Controller, MY_Input …. •
libraries – MY_Email, MY_Upload …. • helpers – MY_array_helper ….
59 $this->load->library('email'); 系統讀取流程
60 讀取優先順序 • application/libraries/MY_Email.php • application/libraries/Email.php • system/libraries/Email.php • application/libraries/MY_email.php
• application/libraries/email.php • system/libraries/email.php
61 擴充 Native Session 支援原生 $_SESSION http://bit.ly/ci-native-session
62 3.0 版本已經支援 Native Session
63 安裝 $ cp config/session.php application/config/ $ cp libraries/Session.php application/libraries/
64 多個 Application 請設定 config $config['sess_namespace'] = '';
65 多國語系 i18n http://bit.ly/ci-i18n
66 擴充 Core Language $ cp application/config/language.php app/application/config/ $ cp
application/core/MY_Lang.php app/application/core/
67 設定 $config['language_field'] = 'lang'; $config['language_key'] = 'en-us'; $config['language_list'] =
array( 'en-us' => 'english', 'zh-tw' => 'zh-tw‘ );
68 使用方式 $this->load->helper('language'); $this->lang->load('welcome'); echo lang('welcome.title');
69 作業二 • 將 Welcome controller 加入 – Native Session
– 多國語言
70 PHP ORM Model CodeIgniter 沒有 ORM 只有 ActiveRecord
71 Codeigniter Base Model http://bit.ly/ci-base-model
72 簡介 class Topic_model extends MY_Model { } $this->load->model('topic_model', 'topic');
$this->topic->get_all(); $this->topic->get(1); $this->topic->get_by('title', 'Pigs CAN Fly!'); $this->topic->get_many_by('status', 'open'); $this->topic->insert(array( 'status' => 'open', 'title' => "I'm too sexy for my shirt" )); $this->topic->update(1, array( 'status' => 'closed' )); $this->topic->delete(1);
73 擴充核心 Model 下載 MY_Model.php 放到 application/core
74 class Topic_model extends MY_Model { } class Topic_m extends
MY_Model { } 命名原則
75 指定資料表 class Topic_model extends MY_Model { public $_table =
‘topics’; }
76 指定 Primary Key // 預設為 id class Topic_model extends
MY_Model { public $primary_key = ‘topic_id'; }
77 Callbacks • $before_create • $after_create • $before_update • $after_update
• $before_get • $after_get • $before_delete • $after_delete
78 範例 class Topic_model extends MY_Model { public $before_create =
array( 'timestamps' ); protected function timestamps($topic) { $topic['created_at'] = date('Y-m-d H:i:s'); $topic['updated_at'] = date('Y-m-d H:i:s'); return $topic; } }
79 參數處理 public $before_create = array('data_process(name)'); public $before_update = array('data_process(date)');
protected function data_process($row) { $row[$this->callback_parameters[0]] = $this- >_process($row[$this->callback_parameters[0]]); return $row; }
80 驗證 Validation class User_model extends MY_Model { public $validate
= array( array( 'field' => 'email', 'label' => 'email', 'rules' => 'required|valid_email|is_unique[users.email]' ), array( 'field' => 'password', 'label' => 'password', 'rules' => 'required' ), array( 'field' => 'password_confirmation', 'label' => 'confirm password', 'rules' => 'required|matches[password]' ), ); }
81 新增修改資料 都會觸發驗證
82 忽略資料驗證 $this->user_model->skip_validation(); $this->user_model->insert(['email' => 'blah'], true);
83 保護欄位 class Topic_model extends MY_Model { public $protected_attributes =
['id']; }
84 $this->topic_model->insert(array( 'id' => 2, 'title' => 'A new topic'
)); // INSERT INTO topics (title) VALUES ('A new topic')
85 Object vs. Array class Topic_model extends MY_Model { protected
$return_type = 'array'; }
86 $this->topic_model ->as_array() ->get(1); $this->topic_model ->as_object() ->get_by('column', 'value');
87 Soft Delete class Topic_model extends MY_Model { protected $soft_delete
= true; protected $soft_delete_key = 'deleted'; }
88 $this->topic_model->get(1); // SELECT * FROM topics WHERE id =
1 and deleted = 0 $this->topic_model->only_deleted()->get(1); // SELECT * FROM topics WHERE id = 1 AND deleted = 1 $this->topic_model->with_deleted()->get(1); // SELECT * FROM topics WHERE id = 1
89 內建 Observers class Topic_model extends MY_Model { public $before_create
= ['created_at', 'updated_at']; public $before_update = ['updated_at']; }
90 資料庫連線 class Topic_model extends MY_Model { public $_db_group =
'group_name'; }
91 作業三 • 實做最新消息系統 – 建立 topics 資料表 • id,
title, description, is_feature, created_at, updated_at • 實做 CRUD ( 新增 , 刪除 , 修改 , 查詢 ) • 實做置頂功能
92 Relationships class Topic_model extends MY_Model { public $belongs_to =
['user']; public $has_many = ['comments']; }
93 新增相關 Model • class User_model extends MY_Model { }
• class Comment_model extends MY_Model { }
94 指定相關資料表 class Topic_model extends MY_Model { public $belongs_to =
['user' => ['model' => 'user_m']]; public $has_many = ['comments' => ['model' => 'model_comments']]; }
95 讀取資料 $topic = $this->topic_model ->with(user') ->with('comments') ->get(1); echo $topic->user->name;
foreach ($topic->comments as $comment) { echo $message; }
96 SQL 表示 • SELECT * FROM users WHERE id
= $topic- >user_id • SELECT * FROM comments WHERE topic_id = $topic->id
97 更換 Primary Key class Topic_model extends MY_Model { public
$belongs_to = ['user' => ['primary_key' => 'post_user_id']]; public $has_many = ['comments' => ['primary_key' => 'parent_topic_id']]; }
98 作業四 • 實做最新消息系統 – 建立 Users 資料表 • id,
username – 增加欄位在 Topic 資料表 • user_id – 顯示使用者帳號在 Topic 列表
99 會員模組 http://bit.ly/ci-ion-auth
100 功能列表 • 會員登入 ( 支援帳號或電子郵件 ) • 會員登出 •
會員註冊 • 會員更新 • 忘記密碼 • 電子郵件認證 • 會員群組權限 • 驗證登入錯誤次數
101 安裝方式 複製相關檔案到對應目錄
102 設定檔資料表 $config['tables']['users'] = 'users'; $config['tables']['groups'] = 'groups'; $config['tables']['users_groups'] =
'users_groups'; $config['tables']['login_attempts'] = 'login_attempts'; $config['join']['users'] = 'user_id'; $config['join']['groups'] = 'group_id';
103 會員認證設定 $config['admin_email'] = "
[email protected]
"; $config['default_group'] = 'members'; $config['admin_group'] =
'admin'; $config['identity'] = 'email'; $config['min_password_length'] = 8; $config['max_password_length'] = 20; $config['email_activation'] = FALSE; $config['manual_activation'] = FALSE; $config['remember_users'] = TRUE; $config['user_expire'] = 86500; $config['user_extend_on_login'] = FALSE; $config['track_login_attempts'] = FALSE; $config['track_login_ip_address'] = TRUE; $config['maximum_login_attempts'] = 3; $config['lockout_time'] = 600; $config['forgot_password_expiration'] = 0;
104 電子郵件表單 $config['email_templates'] = 'auth/email/'; $config['email_activate'] = 'activate.tpl.php'; $config['email_forgot_password'] =
'forgot_password.tpl.php'; $config['email_forgot_password_complete'] = 'new_password.tpl.php';
105 自訂錯誤訊息 • $config['message_start_delimiter'] = '<p>'; • $config['message_end_delimiter'] = '</p>';
• $config['error_start_delimiter'] = '<p>'; • $config['error_end_delimiter'] = '</p>';
106 Template 模組 A Lightweight Codeigniter Template Libray http://bit.ly/ci-template
107 安裝方式 $ php tools/spark install -v1.0.4 codeigniter- template
108 預設模板 $config['template_layout'] = 'template/layout';
109 新增 CSS 連結 $this->template->add_css("/min.css", "screen"); // <link href="/min.css" rel="stylesheet"
type="text/css" media="screen" />
110 新增 JavaScript 連結 $this->template->add_js("/index.js", true); // <script src="/index.js" type="text/javascript"></script>
111 動態新增 Meta Tag $this->template->add_meta_tag("og:title", "Test Title", 'property'); //output <meta
property="og:title" content="Test Title" /> $this->template->add_meta_tag("keywords", "some keywords"); // output <meta name="keywords" content="some keywords" />
112 動態標題 $this->template->add_title_segment('test'); // output <title>test | your site title</title>
113 動態設定值 $this->template->set("is_login", false); or $this->template->is_login = false;
114 $this->template->render('index', $data); 輸出畫面
115 作業五 • 整合會員到最新消息系統 – 登入後才可以修改及發表 – 管理者才可以刪除文章 • 整合
Template 模組 – 加入 jQuery 元件 http://jquery.com/ – 加入 Bootstraphttp://getbootstrap.com/
116 CodeIgniter RESTful API Design
117 RESTful Representational State Transfer 各大網站 Google Amazone Yahoo 都提供
RESTful API
118 HTTP Methods • GET => 讀取 • PUT =>
更新 • POST => 新增 • DELETE => 刪除
119 格式 Format JSON, XML 你不可不知的 JSON 基本介紹
120 JSON usage in JavaScript var output = { ‘title’:
‘I am appleboy.’, ‘desctiption’: ‘CodeIgniter in Action.’ };
121 JSON usage in PHP json_encode * http://bit.ly/php-json-encode json_decode *
http://bit.ly/php-json-decode
122 傳統 • /topic/create • /topic/show/1 • /topic/update/1 • /topic/destroy/1
123 傳統 • /topic/create • /topic/show/1 • /topic/update/1 • /topic/destroy/1
現在 • POST /topic • GET /topic/1 • PUT /topic/1 • DELETE /topic/1
124 CodeIgniter RESTful Server http://bit.ly/ci-reset-server
125 安裝方式 • application/libraries/Format.php • application/libraries/REST_Controller.php • application/config/rest.php
126 範例 class Topic extends REST_Controller { public function index_get()
{ // Display all topics } public function index_post() { // Create a new topic } }
127 參數 • $this->get('blah'); // GET • $this->post('blah'); // POST
• $this->put('blah'); // PUT • $this->delete('blah'); // DELETE
128 Response 回覆 public function index_delete($id) { $this->response([ 'returned from
delete:' => $id, ]); }
129 Response 回覆 • // Send an HTTP 201 Created
• $this->response($book, 201); • // HTTP 404 Not Found • $this->response([]);
130 支援 API Keys • $config['rest_enable_keys'] = TRUE;
131 建立 API KEY 資料表 CREATE TABLE `keys` ( `id`
int(11) NOT NULL AUTO_INCREMENT, `key` varchar(40) NOT NULL, `level` int(2) NOT NULL, `ignore_limits` tinyint(1) NOT NULL DEFAULT '0', `date_created` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
132 測試 API KEY $ curl -X POST -H "X-API-KEY:
some_key_here" http://example.com/topics
133 作業六 • 實作 Topic RESTful API 撰寫 – /api/topic
GET 新聞列表 – /api/topic/{id} GET 單一新聞列表 – /api/topic/{id} PUT 更新新聞 – /api/topic POST 建立新聞 – /api/topic/{id} DELETE 刪除新聞 • 用 jQuery AJAX 搭配後端 CRUD 功能 • 整合 Facebook 登入 API
134 作業程式碼 https://github.com/appleboy/CodeIgniter-App
135 參考文獻 • CodeIgniter 台灣官網 – http://codeigniter.org.tw/ • 被遺忘的資訊洩漏-重點回顧 –
http://goo.gl/UO7Akz
136 謝謝大家參與 謝謝主辦單位