日期:106年9月13日 – 9月27日
時間:週三下午
地點:新北市教研中心
公文與計畫:
課程主題:PHP 框架 CodeIgniter 3
- CodeIgniter 繁體中文官方網站
- CodeIgniter 使用手冊— CodeIgniter 3.1.5 documentation
講師:樹林國小黃保太老師
開發環境與工具:
- Wagon 的下載及設定
- wagon-1.3.1.7z
- 免安裝可攜的 LARAVEL 開發環境
- wagon on github
- 注意事項:解壓縮後,須設定該資料夾的安全性,使 Users 群組設為可「修改」,如此在啟動及關閉 uwAmp 時,才不會出問題。
- PhpStorm
- GitKraken: Git GUI for Windows, Mac & Linux
【學習資源】【九月13日】【九月20日】【九月27日】
課後補充教材:
- CodeIgniter3 Linux開發環境0001 ~ 0003
- CodeIgniter3 上傳XML、解析、寫入資料庫01 ~ 05
講義:1060927_PHP_Framework_Codeigniter(三)
課程網站資料下載:
教學相關網站:
- NTPC OpenID:http://openid.ntpc.edu.tw
- 欄位規格說明
- 範例程式下載
- 注意事項:
openid 的範例中,openid.php 這支library裡在 #280, #293, #309 這三行中,判斷 ssl 的 CN_match 這個設定已不再使用(deprecated)。apache2 目前似乎仍可正常使用,不過,放在 nginx 的話,會噴錯誤,將 ‘CN_match’ 自行改成 ‘peer_name’ 可正常執行。
- OpenID – 維基百科,自由的百科全書
- 認識 RESTful API:https://www.youtube.com/watch?v=gHCB0sd47Is&t=4
- REST – 維基百科,自由的百科全書
- 簡明RESTful API設計要點
教學內容:
application\views\auth\form.php
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<?php foreach( $menu as $key => $value): ?>
<li>
<a href="<?=base_url()?><?=$value?>"><?=$key?></a>
</li>
<?php endforeach; ?>
</ul>
</div>
...
<!-- Post Content -->
...
<ul>
<form action="/ntpc_openid_login" method="post">
<input
class="btn-info btn-lg"
type="submit"
value="新北市OpenID登入"
>
</form>
</ul>
application\views\template\main.php
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<?php foreach( $menu as $key => $value): ?>
<li>
<a href="<?=base_url()?><?=$value?>"><?=$key?></a>
</li>
<?php endforeach; ?>
<?php if($this->session->is_logined ) :?>
<li>
<a href="user/" title="<?=$cname?>"><?=$account?></a>
</li>
<li>
<a href="<?=base_url()?>auth/logout" title="登出">登出</a>
</li>
<?php endif; ?>
</ul>
</div>
...
<!-- Post Content -->
<ul>
<?php if( isset($posts) ) : ?>
<?php foreach( $posts->result() as $row ): ?>
<li class="lead">
<a href="/post/post_desc/<?=$row->id?>"><?=$row->post_title?></a>
<?php if( $is_logined and $level >=100 ): ?>
<a class="btn-danger" href="/post/delete/<?=$row->id?>">刪</a>
<?php endif; ?>
</li>
<?php endforeach; ?>
<?php endif; ?>
</ul>
application\helpers\utility_helper.php
function get_default_data(){
$data["title"] = '語文競賽報名系統';
$data["menu"] = array(
"說明" => "welcome",
//"報名" => "enroll",
"清單" => "post/show",
"登入" => "auth/form"
//"個人資訊" => "userinfo",
//"admin" => "系統管理",
);
return $data;
}
application\controllers\Auth.php
class Auth extends CI_Controller
{
public function index()
{
$data = get_default_data();
$this->load->library('form_validation');
$this->load->view('auth/form', $data);
}
public function form()
{
$data = get_default_data();
$this->load->library('form_validation');
$this->load->view( "auth/form", $data);
}
public function form_validation()
{
$data = get_default_data();
$this->load->helper("url");
$this->load->library(
array('form_validation')
);
$this->form_validation->set_rules('username', '帳號', 'required');
$this->form_validation->set_rules('password', '密碼', 'required');
if( $this->form_validation->run() == false){
$this->load->view("auth/form", $data);
}else{
$username = $this->input->post("username");
$password = $this->input->post("password");
}
}
public function do_openid_login()
{
require_once APPPATH . '../assets/openid/openid.php';
$openid = new LightOpenID('localhost');
if (!$openid->mode) {
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$openid->identity = 'http://openid.ntpc.edu.tw/';
$openid->required = array(
'namePerson/friendly',
'contact/email',
'namePerson',
'birthDate',
'person/gender',
'contact/postalCode/home',
'contact/country/home',
'pref/language',
'pref/timezone'
);
header('Location: ' . $openid->authUrl());
}else{
}
}
}
public function get_openid_data()
{
require_once APPPATH . '../assets/openid/openid.php';
$openid = new LightOpenID('localhost');
$this->load->helper('url');
if (!$openid->mode){
redirect(base_url() . 'auth/form');
}elseif( $openid->mode == 'cancel') {
print "使用者取消";
}else{
if ($openid->validate()) {
$attr = $openid->getAttributes();
$tmp =explode('/', $openid->identity );
$userinfo["account"] = end( $tmp );
$userinfo["cname"] = $attr['namePerson'];
$userinfo["birth"] = $attr['birthDate'];
$userinfo["school_name"] = $attr['contact/country/home'];
$userinfo["email"] = $attr['contact/email'];
$this->session->userinfo = $userinfo;
$this->session->is_logined = true;
$this->session->account = $userinfo['account'];
$titles = array();
$groups = array();
foreach (json_decode($attr['pref/timezone']) as $item) {
$titles[] = $item->title;
$groups[] = implode('、', $item->groups);
}
$this->session->titles = $titles;
$this->session->groups = $groups;
if( in_array("資訊組長", $groups)){
$this->session->level = 999;
}elseif( in_array("導師", $groups)){
$this->session->level = 10;
}
/*dump( $userinfo );
dump( $this->session );*/
redirect ('post/show');
}
}
}
public function logout()
{
$this->session->sess_destroy();
redirect( base_url() . "post/show");
}
}
application\controllers\Post.php
public function show()
{
$data = get_default_data();
$data['account'] = $this->session->account;
$data['is_logined'] = $this->session->is_logined;
$data['level'] = $this->session->level;
$data['cname'] = $this->session->userinfo['cname'];
$query = null;
if( ! empty($this->uri->segment(3)) ){
$query = $this->p->post($this->uri->segment(3));
}else{
$query = $this->p->posts();
}
$data["posts"] = $query;
$this->load->view('template/main', $data);
}
...
public function delete()
{
$this->load->helper('url');
if( empty( $this->uri->segment(3)) ){
redirect(base_url() . 'post/show');
}else{
$this->p->delete( $this->uri->segment(3) );
redirect(base_url() . 'post/show');
}
}
application\config\autoload.php
$autoload['libraries'] = array(
'database', 'session'
);
...
$autoload['helper'] = array(
'url', 'form', 'utility'
);
application\config\config.php
- 在網站根目錄要建一個 sessions 資料夾
$config['sess_save_path'] = APPPATH . '../sessions';
application\config\routes.php
$route['default_controller'] = 'auth';
...
$route['ntpc_openid_login']['post'] = 'auth/do_openid_login';
$route['ntpc_openid_login']['get'] = 'auth/get_openid_data';
assets\openid\index.php
try {
$openid = new LightOpenID('localhost');
if (!$openid->mode) {
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$openid->identity = 'http://openid.ntpc.edu.tw/';
$openid->required = array(
'namePerson/friendly',
'contact/email',
'namePerson',
'birthDate',
'person/gender',
'contact/postalCode/home',
'contact/country/home',
'pref/language',
'pref/timezone'
);
header('Location: ' . $openid->authUrl());
}
...
} else {
if ($openid->validate()) {
$attr = $openid->getAttributes();
$tmp =explode('/', $openid->identity);
$myid = end( $tmp );
echo '<table border="1" cellspacing="0" cellpadding="10">';
echo '<tr><td>帳號</td><td>' . $myid . '</td></tr>';
...
}
}
} catch (ErrorException $e) {
echo $e->getMessage();
}
【學習資源】【九月13日】【九月20日】【九月27日】
講義:1060920_PHP_Framework_Codeigniter(二)
教學影片:
20170920-CodeIgniter3 MVC開發
PHP Composer
- Laradebut #11 Composer 新手入門教學 一學就上手 by 閃亮亮
- COMPOSER設計原理與基本用法
- COMPOSER進階原理:PHP命名空間與PSR-0
- 不專業網管筆記 | 林士立老師
- Composer 官方網站 (英文版)
- Composer | 正體中文文件
- Packagist – The PHP Package Repository
- dg/rss-php: RSS & Atom Feeds for PHP is a very small and easy-to-use library for consuming an RSS and Atom feed
範例:蘋果日報 RSS 剖析
- composer self-update
- cd CodeIgniter-3.1.5
- composer require dg/rss-php
CodeIgniter 3 文件:輔助函式
教學內容:
application\config\autoload.php
/*
| -------------------------------------------------------------------
| Auto-load Helper Files
| -------------------------------------------------------------------
| Prototype:
|
| $autoload['helper'] = array('url', 'file');
*/
$autoload['helper'] = array(
'utility_helper'
);
application\config\config.php
$config['base_url'] = 'http://localhost'; ...
//$config['language'] = 'english'; $config['language'] = 'zh-tw';
...
//$config['composer_autoload'] = FALSE; $config['composer_autoload'] = APPPATH . '../vendor/autoload.php';
application\helpers\utility_helper.php
function dump($obj){
print "<pre>";
var_dump($obj);
print "</pre>";
}
function echobr($str){
print $str . '<br />';
}
function get_default_data(){
$data["title"] = '語文競賽報名系統';
$data["menu"] = array(
"about" => "說明",
"enroll" => "報名",
"list" => "清單",
"userinfo" => "個人資訊",
"admin" => "系統管理",
);
return $data;
}
application\models\Post_model.php
class Post_model extends CI_Model
{
public function __construct()
{
parent::__construct();
$this->load->database();
}
public function posts()
{
$this->db->select("*");
//$this->db->where('id', 5);
//$this->db->order_by('created_time', "DESC");
$this->db->order_by('id', "DESC");
$query = $this->db->get('post');
return $query;
}
public function post($post_id = null)
{
if( $post_id == null ) return null;
$this->db->select("*");
$this->db->where('id', $post_id);
$query = $this->db->get('post');
return $query;
}
public function add($title=null, $content=null)
{
$data = array(
'post_title' => $title,
'post_content' => $content
);
$this->db->insert( 'post', $data );
}
public function delete($post_id = null)
{
if( $post_id == null ) return null;
$data = array(
'id' => $post_id
);
$this->db->delete('post', $data);
}
public function update()
{
}
}
application\controllers\Test.php
class Test extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->helper('utility_helper');
}
public function rss()
{
$this->load->helper('utility_helper');
$this->load->model('post_model');
date_default_timezone_set("asia/taipei");
$rss_url = 'http://www.appledaily.com.tw/rss/newcreate/kind/rnews/type/new';
$rss = Feed::loadRss($rss_url);
echo 'Title: ', $rss->title . '<br />';
echo 'Description: ', $rss->description . '<br />';
echo 'Link: ', $rss->link . '<br />';
$num = 0;
foreach ($rss->item as $item) {
//dump( $item );
/*echo 'Title: ', $item->title . '<br />';
echo 'Link: ', $item->link . '<br />';
echo 'Timestamp: ', $item->timestamp . '<br />';
echo 'Description ', $item->description . '<br />';
echo 'HTML encoded content: ', $item->{'content:encoded'} . '<br />';*/
$this->post_model->add($item->title, $item->description );
$num++;
}
echobr('post add ' . $num . ' records.');
/*$data = array(
'name' => 'bob',
'age' => 40,
'school_name' => 'Shulin Primary School'
);
dump($data);*/
}
public function test_model()
{
$this->load->model('post_model');
//dump( $this->post_model->posts() );
$this->post_model->add('aaaaaaa', 'bbbbbbbbbbbbbbbbbbbb');
print "insert ok";
}
}
application\controllers\Auth.php
class Auth extends CI_Controller
{
public function index()
{
$data = get_default_data();
$this->load->view('template/main', $data);
}
public function form()
{
$data = get_default_data();
$this->load->library('form_validation');
$this->load->view( "auth/form", $data);
}
public function form_validation()
{
$data = get_default_data();
$this->load->helper("url");
$this->load->library(
array('form_validation')
);
$this->form_validation->set_rules('username', '帳號', 'required');
$this->form_validation->set_rules('password', '密碼', 'required');
if( $this->form_validation->run() == false){
$this->load->view("auth/form", $data);
}else{
$username = $this->input->post("username");
$password = $this->input->post("password");
}
}
}
application\controllers\Post.php
class Post extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('post_model', 'p');
}
...
...
public function delete()
{
$this->load->helper('url');
if( empty( $this->uri->segment(3)) ){
//redirect('post/show');
//echobr( base_url() );
redirect(base_url() . 'post/show');
//$this->show();
}else{
$this->p->delete( $this->uri->segment(3) );
redirect(base_url() . 'post/show');
//$this->show();
}
}
}
複製 system\language\english -> application\language\zh-tw
application\language\zh-tw\form_validation_lang.php
$lang['form_validation_required'] = '【{field}】 這個欄位必須輸入資料';
application\views\auth\form.php
<!-- Post Content -->
<ul>
<form action="/auth/form_validation" method="post">
帳號: <input type="text" name="username" id="username">
<span class="text-danger"><?=form_error("username")?></span>
密碼: <input type="password" name="password" id="password">
<span class="text-danger"><?=form_error("password")?></span>
<input type="submit" value="登入">
</form>
</ul>
【學習資源】【九月13日】【九月20日】【九月27日】
課程講義:1060913_PHP_Framework_Codeigniter
教學影片:
保太教學錄影:
PHP Codeigniter Step By Step Tutorials for Beginners 2017
教學內容:
application\controllers\Welcome.php
class Welcome extends CI_Controller
{
public function index()
{
$this->load->view('welcome_message');
}
public function hello(){
print "<h1>";
print "大家好,歡迎來到 CodeIgniter 3!";
print "</h1>";
}
public function bye(){
$data["title"] = '語文競賽報名系統';
$data["menu"] = array(
"about" => "說明",
"enroll" => "報名",
"list" => "清單",
"userinfo" => "個人資訊",
"admin" => "系統管理",
);
$this->load->view('template/main', $data);
}
}
application\controllers\Auth.php
class Auth extends CI_Controller
{
public function index(){
$data["title"] = '語文競賽報名系統';
$data["menu"] = array(
"about" => "說明",
"enroll" => "報名",
"list" => "清單",
"userinfo" => "個人資訊",
"admin" => "系統管理",
);
$this->load->database();
//$query = $this->db->query("select * from post");
$this->db->select('id, post_title, post_content, created_time, updated_time');
$this->db->from('post');
if( ! empty($this->uri->segment(3)) ){
$this->db->where('id', $this->uri->segment(3));
}
$query = $this->db->get();
$data["posts"] = $query;
$this->load->view('template/main', $data);
}
}
application\controllers\Post.php
class Post extends CI_Controller
{
public function show(){
$this->load->database();
$data["title"] = '語文競賽報名系統';
$data["menu"] = array(
"about" => "說明",
"enroll" => "報名",
"list" => "清單",
"userinfo" => "個人資訊",
"admin" => "系統管理",
);
$this->db->select('id, post_title, post_content, created_time, updated_time');
$this->db->from('post');
if( ! empty($this->uri->segment(3)) ){
$this->db->where('id', $this->uri->segment(3));
}
$query = $this->db->get();
$data["posts"] = $query;
$this->load->view('template/header', $data);
$this->load->view('template/menu', $data);
$this->load->view('template/title_block', $data);
$this->load->view('template/content', $data);
$this->load->view('template/footer', $data);
}
public function post_desc(){
$this->load->database();
if( empty($this->uri->segment(3)) ) redirect("/post/show");
$data["title"] = '語文競賽報名系統';
$data["menu"] = array(
"about" => "說明",
"enroll" => "報名",
"list" => "清單",
"userinfo" => "個人資訊",
"admin" => "系統管理",
);
$this->db->select('id, post_title, post_content, created_time, updated_time');
$this->db->from('post');
if( ! empty( $this->uri->segment(3)) ){
$this->db->where('id', $this->uri->segment(3));
}
$query = $this->db->get();
$data["posts"] = $query;
$this->load->view('template/post_desc', $data);
}
}
.htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
application\config\database.php
$db['default'] = array(
'dsn' => '',
'hostname' => 'localhost',
'username' => 'blogadm',
'password' => '!2345678',
'database' => 'blog',
'dbdriver' => 'mysqli',
'dbprefix' => '',
'pconnect' => FALSE,
'db_debug' => (ENVIRONMENT !== 'production'),
'cache_on' => FALSE,
'cachedir' => '',
'char_set' => 'utf8',
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'encrypt' => FALSE,
'compress' => FALSE,
'stricton' => FALSE,
'failover' => array(),
'save_queries' => TRUE
);
application\views\template\main.php
<head> ... <!-- Bootstrap Core CSS --> <link href="/assets/css/bootstrap.min.css" rel="stylesheet"> <!-- Custom CSS --> <link href="/assets/css/blog-post.css" rel="stylesheet"> ... </head> <body> ...
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <?php foreach( $menu as $key => $value): ?> <li> <a href="#"><?=$value?></a> </li> <?php endforeach; ?> </ul> </div> ...
<!-- Title --> <h1><?=$title?></h1> ... <!-- Post Content --> <ul> <?php foreach( $posts->result() as $row ): ?> <li class="lead"> <a href="/post/post_desc/<?=$row->id?>"><?=$row->post_title?></a> <a href="/post/delete/<?=$row->id?>">刪</a> </li> <?php endforeach; ?> </ul>
...
<!-- jQuery --> <script src="/assets/js/jquery.js"></script> <!-- Bootstrap Core JavaScript --> <script src="/assets/js/bootstrap.min.js"></script>
</body>