Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

You must know about CodeIgniter Popular Library

7,173 views

Published on

實戰 CodeIgniter

Published in: Technology

You must know about CodeIgniter Popular Library

  1. 1. 1 實戰 CodeIgniter PHP Framework Bo-Yi Wu (appleboy) 2014.09.26 成功大學電算中心
  2. 2. 2 關於我 Bo-Yi Wu (appleboy) – Blog: http://blog.wu-boy.com/ – Github: https://github.com/appleboy – CodeIgniter站長 – Laravel站長
  3. 3. 3 為什麼要使用Framework Why should I use a framework ?
  4. 4. 4 不用重新造輪子 Not having to reinvent the wheel
  5. 5. 5 容易升級與維護 upgradability and maintenance
  6. 6. 6 既定開發流程 Develop Flow
  7. 7. 7 網站安全性 Web Security
  8. 8. 8 網站安全性 • 管理介面 URL ● 目錄 (Index of) ● 錯誤訊息 ● 暫存測試資訊 ● 版本控管 ● SQL Injection
  9. 9. 9 Joomla管理介面
  10. 10. 10 早期phpMyAdmin有漏洞風險
  11. 11. 11 常用管理介面路徑 ● /admin/ ● /phpMyAdmin/ ● /adminLogin/ ● /manage/ ● /management/ ● /root/ ● /wp-admin/ 政府機關、學校機構、電信業者
  12. 12. 12 如何防禦 ● 限制存取IP(Apache, Nginx) ● 隱藏管理介面(複雜目錄名稱) ● 增加後台防禦(Captcha …)
  13. 13. 13 網站安全性 ● 管理介面 URL • 目錄 (Index of) ● 錯誤訊息 ● 暫存測試資訊 ● 版本控管 ● SQL Injection
  14. 14. 14
  15. 15. 15 Index of ● 網路目錄結構曝光 ● 存取敏感檔案 – .bak – config.php.bak – .svn, .git, – database.yml
  16. 16. 16 如何防禦 關閉Index功能(Apache) <Directory /> Options -Indexes </Directory>
  17. 17. 17 網站安全性 ● 管理介面 URL ● 目錄 (Index of) • 錯誤訊息 ● 暫存測試資訊 ● 版本控管 ● SQL Injection
  18. 18. SQL 錯誤訊息18
  19. 19. 19 如何防禦 ● 關閉錯誤顯示 – php.ini – display_errors = off ● 使用 Framework 都可以直接設定在專案裡
  20. 20. 20 網站安全性 ● 管理介面 URL ● 目錄 (Index of) ● 錯誤訊息 • 暫存測試資訊 ● 版本控管 ● SQL Injection
  21. 21. 21 暫存測試資訊 ● 開發者求方便使用檔名備份 – .bak, xxx.php2 ● 編輯器自動備份 – index.php~, index.php.swp ● 看系統資訊 – phpinfo.php
  22. 22. 22 不要在Production機器上 改程式碼 set vim :set nobackup
  23. 23. 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. 24. 24 網站安全性 ● 管理介面 URL ● 目錄 (Index of) ● 錯誤訊息 ● 暫存測試資訊 • 版本控管 ● SQL Injection
  25. 25. 25 版本控管 http://xxxx.com/.git/config http://xxxx.com/.git http://xxxx.com/.svn
  26. 26. 26
  27. 27. 27 如何防禦 ● 開發環境跟正式環境切開 ● 禁止版本控制資料夾存取 ● 導入Deploy流程(Continuous Integration)
  28. 28. 28 網站安全性 ● 管理介面 URL ● 目錄 (Index of) ● 錯誤訊息 ● 暫存測試資訊 ● 版本控管 • SQL Injection
  29. 29. 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. 30. 30 如何防禦 ● 請不要相信使用者任何輸入字串 ● 正規比對格式 – preg_match(‘/^(w)+$/’, $string); – 使用framework提供escape函式 ● 型態轉換Typecasting
  31. 31. 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. 32. 32 選擇 PHP Framework
  33. 33. 33
  34. 34. 34
  35. 35. 35 為什麼要選擇 CodeIgniter ● 安裝容易 ● 輕易上手 ● 繁中文件
  36. 36. 36 安裝容易 wget + unzip = done
  37. 37. 37 輕易上手 只要會一點點物件導向即可
  38. 38. 38 繁中文件 目前只有CodeIgniter、Laravel有繁中文件 http://codeigniter.org.tw/user_guide/ http://bit.ly/ci-userguide
  39. 39. 39 CodeIgniter3.0發展 目前最新為2.2.0版本
  40. 40. 40 EllisLab Seeking New Owner for CodeIgniter http://bit.ly/ci-seek-new-owner
  41. 41. 41
  42. 42. 42 3.0版本有超過 100個bug fixed 100個feature commit http://bit.ly/ci-changelog
  43. 43. 43 CodeIgniter 架構
  44. 44. 44 CodeIgniter架構 ● application開發MVC程式碼 ● system系統程式碼 ● user_guide線上文件 ● index.php主檔案
  45. 45. 45 index.php ● $application_folder = 'application'; ● $system_path = 'system';
  46. 46. 更動Web架構 46
  47. 47. 47 CodeIgniter架構 ● application ● system ● public/index.php ● public/robots.txt ● Public/.htaccess
  48. 48. 48 index.php ● $application_folder = ‘../application'; ● $system_path = ‘../system';
  49. 49. 49 使用者無法存取 index.php以外的檔案 Apache: DocumentRoot /xxx/public Nginx: root /xxx/public
  50. 50. 50 隱藏URL index.php字串
  51. 51. 51 Apache RewriteEngine on RewriteBase / RewriteCond $1 !^(index.php|robots.txt|$) RewriteRule ^(.*)$ index.php/$1 [L,QSA]
  52. 52. 52 Nginx location / { try_files $uri $uri/ /index.php?$query_string; }
  53. 53. 使用此架構好處 53 ● 避免.git 曝露 ● 根目錄可以放其他設定檔 – .editorconfig – .gitignore – gulpfile.coffee – bower.js – package.json
  54. 54. 54 作業一 ● 建立一個virtual host: ci.localhost ● 安裝codeigniter 2.2.0 ● 移除url的index.php字串 – http://ci.localhost/welcome
  55. 55. 55 CodeIgniter核心架構
  56. 56. 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. 57. 57 核心函式不夠用 擴充核心函式庫
  58. 58. 58 擴充核心函式庫 ● core – MY_Model, MY_Controller, MY_Input …. ● libraries – MY_Email, MY_Upload …. ● helpers – MY_array_helper ….
  59. 59. 59 $this->load->library('email'); 系統讀取流程
  60. 60. 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. 61. 61 擴充Native Session 支援原生$_SESSION http://bit.ly/ci-native-session
  62. 62. 62 3.0 版本已經支援 Native Session
  63. 63. 63 安裝 $ cp config/session.php application/config/ $ cp libraries/Session.php application/libraries/
  64. 64. 64 多個Application請設定config $config['sess_namespace'] = '';
  65. 65. 65 多國語系i18n http://bit.ly/ci-i18n
  66. 66. 擴充Core Language $ cp application/config/language.php app/application/config/ $ cp application/core/MY_Lang.php app/application/core/ 66
  67. 67. 67 設定 $config['language_field'] = 'lang'; $config['language_key'] = 'en-us'; $config['language_list'] = array( 'en-us' => 'english', 'zh-tw' => 'zh-tw‘ );
  68. 68. 68 使用方式 $this->load->helper('language'); $this->lang->load('welcome'); echo lang('welcome.title');
  69. 69. 69 作業二 ● 將Welcome controller加入 – Native Session – 多國語言
  70. 70. 70 PHP ORM Model CodeIgniter沒有ORM 只有ActiveRecord
  71. 71. Codeigniter Base Model 71 http://bit.ly/ci-base-model
  72. 72. 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. 73. 擴充核心Model 下載MY_Model.php 放到 73 application/core
  74. 74. 74 命名原則 class Topic_model extends MY_Model { } class Topic_m extends MY_Model { }
  75. 75. 75 指定資料表 class Topic_model extends MY_Model { public $_table = ‘topics’; }
  76. 76. 76 指定Primary Key // 預設為id class Topic_model extends MY_Model { public $primary_key = ‘topic_id'; }
  77. 77. 77 Callbacks ● $before_create ● $after_create ● $before_update ● $after_update ● $before_get ● $after_get ● $before_delete ● $after_delete
  78. 78. 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. 79. 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. 80. 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. 81. 81 新增修改資料 都會觸發驗證
  82. 82. 82 忽略資料驗證 $this->user_model->skip_validation(); $this->user_model->insert(['email' => 'blah'], true);
  83. 83. 83 保護欄位 class Topic_model extends MY_Model { public $protected_attributes = ['id']; }
  84. 84. 84 $this->topic_model->insert(array( 'id' => 2, 'title' => 'A new topic' )); // INSERT INTO topics (title) VALUES ('A new topic')
  85. 85. 85 Object vs. Array class Topic_model extends MY_Model { protected $return_type = 'array'; }
  86. 86. $this->topic_model ->as_array() ->get(1); $this->topic_model ->as_object() ->get_by('column', 'value'); 86
  87. 87. 87 Soft Delete class Topic_model extends MY_Model { protected $soft_delete = true; protected $soft_delete_key = 'deleted'; }
  88. 88. 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. 89. 89 內建Observers class Topic_model extends MY_Model { public $before_create = ['created_at', 'updated_at']; public $before_update = ['updated_at']; }
  90. 90. 90 資料庫連線 class Topic_model extends MY_Model { public $_db_group = 'group_name'; }
  91. 91. 91 作業三 ● 實做最新消息系統 – 建立 topics 資料表 ● id, title, description, is_feature, created_at, updated_at ● 實做CRUD (新增, 刪除, 修改, 查詢) ● 實做置頂功能
  92. 92. 92 Relationships class Topic_model extends MY_Model { public $belongs_to = ['user']; public $has_many = ['comments']; }
  93. 93. 93 新增相關 Model ● class User_model extends MY_Model { } ● class Comment_model extends MY_Model { }
  94. 94. 94 指定相關資料表 class Topic_model extends MY_Model { public $belongs_to = ['user' => ['model' => 'user_m']]; public $has_many = ['comments' => ['model' => 'model_comments']]; }
  95. 95. 95 讀取資料 $topic = $this->topic_model ->with(user') ->with('comments') ->get(1); echo $topic->user->name; foreach ($topic->comments as $comment) { echo $message; }
  96. 96. 96 SQL 表示 ● SELECT * FROM users WHERE id = $topic- >user_id ● SELECT * FROM comments WHERE topic_id = $topic->id
  97. 97. 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. 98. 98 作業四 ● 實做最新消息系統 – 建立 Users 資料表 ● id, username – 增加欄位在Topic資料表 ● user_id – 顯示使用者帳號在Topic列表
  99. 99. 99 會員模組 http://bit.ly/ci-ion-auth
  100. 100. 100 功能列表 ● 會員登入 (支援帳號或電子郵件) ● 會員登出 ● 會員註冊 ● 會員更新 ● 忘記密碼 ● 電子郵件認證 ● 會員群組權限 ● 驗證登入錯誤次數
  101. 101. 101 安裝方式 複製相關檔案到對應目錄
  102. 102. 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. 103. 103 會員認證設定 $config['admin_email'] = "admin@example.com"; $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. 104. 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. 105. 105 自訂錯誤訊息 ● $config['message_start_delimiter'] = '<p>'; ● $config['message_end_delimiter'] = '</p>'; ● $config['error_start_delimiter'] = '<p>'; ● $config['error_end_delimiter'] = '</p>';
  106. 106. Template模組 106 A Lightweight Codeigniter Template Libray http://bit.ly/ci-template
  107. 107. 107 安裝方式 $ php tools/spark install -v1.0.4 codeigniter-template
  108. 108. 108 預設模板 $config['template_layout'] = 'template/layout';
  109. 109. 新增CSS連結 $this->template->add_css("/min.css", "screen"); // <link href="/min.css" rel="stylesheet" type="text/css" media="screen" /> 109
  110. 110. 新增JavaScript連結 $this->template->add_js("/index.js", true); // <script src="/index.js" type="text/javascript"></script> 110
  111. 111. 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. 112. 112 動態標題 $this->template->add_title_segment('test'); // output <title>test | your site title</title>
  113. 113. 113 動態設定值 $this->template->set("is_login", false); or $this->template->is_login = false;
  114. 114. 114 輸出畫面 $this->template->render('index', $data);
  115. 115. 115 作業五 ● 整合會員到最新消息系統 – 登入後才可以修改及發表 – 管理者才可以刪除文章 ● 整合Template模組 – 加入jQuery元件http://jquery.com/ – 加入Bootstraphttp://getbootstrap.com/
  116. 116. 116 CodeIgniter RESTful API Design
  117. 117. 117 RESTful Representational State Transfer 各大網站Google Amazone Yahoo都提供 RESTful API
  118. 118. 118 HTTP Methods ● GET => 讀取 ● PUT => 更新 ● POST => 新增 ● DELETE => 刪除
  119. 119. 119 格式Format JSON, XML 你不可不知的 JSON 基本介紹
  120. 120. 120 JSON usage in JavaScript var output = { ‘title’: ‘I am appleboy.’, ‘desctiption’: ‘CodeIgniter in Action.’ };
  121. 121. 121 JSON usage in PHP json_encode * http://bit.ly/php-json-encode json_decode * http://bit.ly/php-json-decode
  122. 122. 122 傳統 ● /topic/create ● /topic/show/1 ● /topic/update/1 ● /topic/destroy/1
  123. 123. 123 傳統 ● /topic/create ● /topic/show/1 ● /topic/update/1 ● /topic/destroy/1 現在 ● POST /topic ● GET /topic/1 ● PUT /topic/1 ● DELETE /topic/1
  124. 124. CodeIgniter RESTful Server 124 http://bit.ly/ci-reset-server
  125. 125. 安裝方式 125 ● application/libraries/Format.php ● application/libraries/REST_Controller.php ● application/config/rest.php
  126. 126. 範例 126 class Topic extends REST_Controller { public function index_get() { // Display all topics } public function index_post() { // Create a new topic } }
  127. 127. 參數 127 ● $this->get('blah'); // GET ● $this->post('blah'); // POST ● $this->put('blah'); // PUT ● $this->delete('blah'); // DELETE
  128. 128. Response回覆 128 public function index_delete($id) { $this->response([ 'returned from delete:' => $id, ]); }
  129. 129. Response回覆 129 ● // Send an HTTP 201 Created ● $this->response($book, 201); ● // HTTP 404 Not Found ● $this->response([]);
  130. 130. 支援API Keys ● $config['rest_enable_keys'] = TRUE; 130
  131. 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; 131
  132. 132. 測試API KEY $ curl -X POST -H "X-API-KEY: some_key_here" http://example.com/topics 132
  133. 133. 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. 134. 作業程式碼 134 https://github.com/appleboy/CodeIgniter-App
  135. 135. 參考文獻 135 ● CodeIgniter 台灣官網 – http://codeigniter.org.tw/ ● 被遺忘的資訊洩漏-重點回顧 – http://goo.gl/UO7Akz
  136. 136. 136 謝謝大家參與 謝謝主辦單位

×