Slim : 適合前後端分家,後端只用來寫 RESTful API 的 framework。

http://www.9lessons.info/2012/05/create-restful-services-api-in-php.html http://www.9lessons.info/2014/12/create-restful-services-using-slim-php.html http://asika.windspeaker.co/post/3495-php-slim-framework-twig

##其他API參考 http://www.html5rocks.com/en/tutorials/cors/ 現在越來越多人認可這種“一次開發,處處運行”的非原生APP開發了,我們在平時開發中常用的兩套技術棧:1、CoreThink + dcloud + framework7 + cors;2、Ionic+Cordova +CoreThink,全都是開源技術,上手無壓力,之前我們也在OSC上分享過: 非原生App開發的基本步驟(移動端:ionic、cordova,後端:CoreThink)歡迎交流,非原生APP上架蘋果APP store http://www.dcloud.io/index.html

官方教學手冊

可以事情況決定安裝哪個版本 3.0 http://www.slimframework.com/docs/ Slim 3 requires PHP 5.5+ 2.0 http://docs.slimframework.com/ Requires PHP 5.3.0 or newer.

一、 使用composer 安裝slim

建立資料夾以及composer.json檔案

//composer.json
{
    "require": {
        "slim/slim": "~2.0"
    }
}

執行composer

composer install
//如果安裝一直沒有動靜,請留意是否要更新composer版本
//如果有,請按照指示更新

二、直接透過指令安裝

composer require slim/slim "^3.0"

三、直接安裝slim

從這裡複製資料夾 composer/vendor/slim/slim/Slim 這個資料就是Slim的程式包 將他單獨複製到新的資料夾即可單獨安裝Slim

引用composer slim 與 直接引用Slim 差別

事情況以及習慣,首先下面是composer中引用slim的方法

<?php
//引用 vendor/autoload.php
require('vendor/autoload.php');
?>

底下則是直接引用Slim

<?php
require('Slim/Slim.php');
\Slim\Slim::registerAutoloader();
?>

後續範例都會以composer引用的為主。

第一個Hello worlde

新增一個index.php (這裡是slim2的用法)

<?php
//引用 vendor/autoload.php
require('vendor/autoload.php');
//instantiate a slim application
$app = new \Slim\Slim();
//define a HTTP GET route
$app->get('/hello/:name', function ($name) {
    echo "Hello, $name";
});
//run the slim application
$app->run();
?>

運行apache server 打開網址。 http://localhost/slim/index.php/hello/[輸入文字] 就會成功看到畫面摟

##去除網址中的 index.php & 開放跨域請求 一般我們都會移除index.php,讓網址規則能符合Rest風格 底下分別介紹Apache及Nginx複寫網址的做法 Apache 使用htaccess來移除網址中的 index.php 以及開放跨域請求(cross domain access)

RewriteEngine On

# Some hosts may require you to use the `RewriteBase` directive.
# If you need to use the `RewriteBase` directive, it should be the
# absolute physical path to the directory that contains this htaccess file.
#
# RewriteBase /

Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]

有時,可視情況調整httpd.conf 的port對應位置

<VirtualHost *:80>
    ServerAdmin me@mysite.com
    DocumentRoot "/path/www.mysite.com/public_html"
    ServerName mysite.com
    ServerAlias www.mysite.com

    #ErrorLog "logs/mysite.com-error.log"
    #CustomLog "logs/mysite.com-access.log" combined

    <Directory "/path/www.mysite.com/public_html">
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

Nginx Nginx 可以透過 nginx.conf 來調整 port對應位置,以及去除index.php 進入nginx.cond

/path/www.mysite.com/
    public_html/ <-- Document root!
        index.php <-- I instantiate Slim here!
    lib/
        Slim/ <-- I store Slim lib files here!

底下是nginx.conf的片段,透過try_files指定server對應資料夾

server {
    listen       80;
    server_name  www.mysite.com mysite.com;
    root         /path/www.mysite.com/public_html;

    try_files $uri /index.php;

    # this will only pass index.php to the fastcgi process which is generally safer but
    # assumes the whole site is run via Slim.
    location /index.php {
        fastcgi_connect_timeout 3s;     # default of 60s is just too long
        fastcgi_read_timeout 10s;       # default of 60s is just too long
        include fastcgi_params;
        fastcgi_pass 127.0.0.1:9000;    # assumes you are running php-fpm locally on port 9000
    }
}

##路由 Slim framework可以幫助你自行設定路由, 並根據不同的URL請求(例如: GET、POST、PUT、DELETE、OPTION或HEAD)來調用(invoke)不同的函式 如果請求的位置找不到相符的路由,將會自動導向 404 找不到頁面

##路由& HTTP REQUEST

<?php
$app = new \Slim\Slim();

//get
$app->get('/books/:id', function ($id) {
    //Show book identified by $id
});

//post
$app->post('/books', function () {
    //Create book
});

//put
$app->put('/books/:id', function ($id) {
    //Update book identified by $id
});

//delete
$app->delete('/books/:id', function ($id) {
    //Delete book identified by $id
});

//options
$app->options('/books/:id', function ($id) {
    //Return response headers
});
?>

##主流瀏覽器不支援PUT、DELETE、OPTIONS請求 不幸的事,主流瀏覽器都不支援原生PUT、DELETE、OPTIONS請求 通常可以先設定表單method的屬性為POST 在透過 name="_METHOD"來設定PUT、DELETE、OPTIONS,來覆蓋掉POST方法

使用PUT方式,HTML表單可以參考下方設計

<form action="/books/1" method="post">
    ... other form fields here...
    <input type="hidden" name="_METHOD" value="PUT"/>
    <input type="submit" value="Update Book"/>
</form>

使用DELETE方式,HTML表單可以參考下方設計

<form action="/books/1" method="post">
    ... other form fields here...
    <input type="hidden" name="_METHOD" value="DELETE"/>
    <input type="submit" value="Delete Book"/>
</form>

使用OPTIONS方式,HTML表單可以參考下方設計

<form action="/books/1" method="post">
    ... other form fields here...
    <input type="hidden" name="_METHOD" value="OPTIONS"/>
    <input type="submit" value="Update Book"/>
</form>

##同時支援多個HTTP methods 有時會希望可以支援多個HTTP請求方法 例如,同時可以取得GET、POST方法 可以使用 via() 來設定,如下:

<?php
$app = new \Slim\Slim();
$app->map('/foo/bar', function() {
    echo "I respond to multiple HTTP methods!";
})->via('GET', 'POST');
$app->run();
?>

##客製化 HTTP methods via() 路由物件,除了支援一般HTTP methods,也可以自行客製化 例如,你可以自己創造一個FOO HTTP methods

<?php
$app = new \Slim\Slim();
$app->map('/hello', function() {
    echo "Hello";
})->via('FOO');
$app->run();
?>

##URL 參數 在網址中可以夾帶多個參數,例如在下方範例同時可夾帶 :one 和 :two 參數

<?php
$app = new \Slim\Slim();
$app->get('/books/:one/:two', function ($one, $two) {
    echo "The first parameter is " . $one;
    echo "The second parameter is " . $two;
});
?>

##預設URL參數值 某些情況,URL要同時支援有或沒有參數 這時可以用小括弧 (:variable) 以及function($variable=預設值)

<?php 
require('vendor/autoload.php');
$app = new \Slim\Slim();

$app->get('/username/(:name)',function($name='') use ($app) {
   
   if($name==''){
      echo 'no name';
   }else{
      echo 'name is '.$name;
   }
});

##外加條件(conditions) 你可以自行分配(assign)路由參數的條件(conditions) 例如,第二個參數為年分,必須是4個數字 可以這樣設定:

<?php
$app = new \Slim\Slim();
$app->get('/archive/:year', function ($year) {
    echo "You are viewing archives from $year";
})->conditions(array('year' => '(19|20)\d\d'));
?>

如果有些條件是普遍存在, 可以在一開始統一設定 使用 \Slim\Route::getDefaultConditions()

<?php
\Slim\Route::setDefaultConditions(array(
    'firstName' => '[a-zA-Z]{3,}'
));
?>

統一設定的條件,也可以被覆蓋掉

<?php
$app = new \Slim\Slim();
$app->get('/hello/:firstName', $callable)
    ->conditions(array('firstName' => '[a-z]{10,}'));

##置入函式 你可以將函式置入(middleware)路由請求中

<?php
function mw1() {
    echo "This is middleware!";
}
function mw2() {
    echo "This is middleware!";
}
$app = new \Slim\Slim();
$app->get('/foo', 'mw1', 'mw2', function () {
    //callback function... Do something 
});

?>

置入函式可以調用 \Slim\Route 物件

$aBitOfInfo = function (\Slim\Route $route) {
    echo "Current route is " . $route->getName();
};

$app->get('/foo', $aBitOfInfo, function () {
    echo "foo";
});

置入的函式會依序執行,因此要等到最後才會執行callback function 可以使用這樣的機制來設計驗證

<?php
$authenticateForRole = function ( $role = 'member' ) {
    return function () use ( $role ) {
        $user = User::fetchFromDatabaseSomehow();
        if ( $user->belongsToRole($role) === false ) {
            $app = \Slim\Slim::getInstance();
            $app->flash('error', 'Login required');
            $app->redirect('/login');
        }
    };
};
$app = new \Slim\Slim();
$app->get('/foo', $authenticateForRole('admin'), function () {
    //Display admin control panel
});
?>

##路由群組 將路由設定為群組,可以更方便管理同類型的路由 例如,下方將建立books相關的API群組:

<?php
$app = new \Slim\Slim();

// API group
$app->group('/api', function () use ($app) {

    // Library group
    $app->group('/library', function () use ($app) {

				//library本身
        $app->get('/',function(){
        
        });

        // Get book with ID
        $app->get('/books/:id', function ($id) {

        });

        // Update book with ID
        $app->put('/books/:id', function ($id) {

        });

        // Delete book with ID
        $app->delete('/books/:id', function ($id) {

        });

    });

});
?>

可以呼叫

GET    /api/library/
GET    /api/library/books/:id
PUT    /api/library/books/:id
DELETE /api/library/books/:id

##輔助方法 - 輔助流程控制 Slim提供許多輔助方法(helper method)協助你進行流程控制

halt() $app->halt(); 可以用來回傳HTTP回應 (例如: 404, 500, 403) 也可以使用 response物件中的setStatus來設定HTTP回應狀態

<?php
$app = new \Slim\Slim();

//Send a default 500 error response
$app->halt(500);

//Or if you encounter a Balrog...
$app->halt(403, 'You shall not pass!');

response物件中的setStatus
<?php
$app->response->setStatus(400);
<?php
$status = $app->response->getStatus();

Pass() 可以用來跳過目前對應的路由,調用下一個相符的路由。 如果跳過目前路由,但後續沒有可對應的路由,則會返回404錯誤 redirect() 重新導向,可以透過這個方法將使用者引導到其他URL位置 HTTP預設會回應302狀態

<?php
$app = new \Slim\Slim();
$app->get('/foo', function () use ($app) {
    $app->redirect('/bar');
});
$app->run();

可以自行設定回應狀態

<?php
$app = new \Slim\Slim();
$app->get('/old', function () use ($app) {
    $app->redirect('/new', 301);
});
$app->run();

stop() 直接終止Slim App

<?php
$app = new \Slim\Slim();
$app->get('/foo', function () use ($app) {
    echo "You will see this...";
    $app->stop();
    echo "But not this";
});
$app->run();

urlFor() 已命名的路由,可以透過urlFor()來動態產生URL

<?php
$app = new \Slim\Slim();

//Create a named route
$app->get('/hello/:name', function ($name) use ($app) {
    echo "Hello $name";
})->name('hello');

//Generate a URL for the named route
$url = $app->urlFor('hello', array('name' => 'Josh'));

判斷HTTP METHOD

以下列出判斷HTTP METHOD的方式:

/**
 * What is the request method?
 * @return string (e.g. GET, POST, PUT, DELETE)
 */
$app->request->getMethod();

/**
 * Is this a GET request?
 * @return bool
 */
$app->request->isGet();

/**
 * Is this a POST request?
 * @return bool
 */
$app->request->isPost();

/**
 * Is this a PUT request?
 * @return bool
 */
$app->request->isPut();

/**
 * Is this a DELETE request?
 * @return bool
 */
$app->request->isDelete();

/**
 * Is this a HEAD request?
 * @return bool
 */
$app->request->isHead();

/**
 * Is this a OPTIONS request?
 * @return bool
 */
$app->request->isOptions();

/**
 * Is this a PATCH request?
 * @return bool
 */
$app->request->isPatch();

/**
 * Is this a XHR/AJAX request?
 * @return bool
 */
$app->request->isAjax();
Next  Previous

##取得HTTP REQUEST 傳送過來的值 通常表單都會夾帶許多變數值,可以透過下列方式來取得各種HTTP METHOD值

<?php
$app = new \Slim\Slim();

//不分HTTP METHOD,取得值
$paramValue = $app->request->params('paramName');

//GET variable
$paramValue = $app->request->get('paramName');

//POST variable
$paramValue = $app->request->post('paramName');

//PUT variable
$paramValue = $app->request->put('paramName');

//All variable
$allGetVars = $app->request->get();
$allPostVars = $app->request->post();
$allPutVars = $app->request->put();

##取得Body內容 可以取得請求來源的body內容 在Slim解析json或XML時會常用到

<?php
$app = new \Slim\Slim();
$body = $app->request->getBody();

針對json資料,可以透過json_decode來解析來源的資料

//For application/json
$data = json_decode($app->request->getBody());

##ROOT URI 及 Resource URI Slim 提供 request物件,可以用來取得ROOT URI及Resource URI ROOT URI是Slim App的 physical url 例如首頁位置: http://localhost:81/example/slim/ ROOT URI就是 /example/slim Resource URI 例如首頁位置: http://localhost:81/example/slim/ Resource URI就是 /

<?php
$app = new \Slim\Slim();

// Get request object
$req = $app->request;

//Get root URI
$rootUri = $req->getRootUri();

//Get resource URI
$resourceUri = $req->getResourceUri();

##HTTP 輔助函式 Slim 提供許多關於查詢HTTP資訊的輔助函式

<?php
$req = $app->request;

//Content Type (e.g. "application/json;charset=utf-8")
$req->getContentType();

//Media Type (e.g. "application/json")
$req->getMediaType();

//Media Type Params (e.g. [charset => "utf-8"])
$req->getMediaTypeParams();

// Content Charset (e.g. "utf-8")
$req->getContentCharset();

//Content Length 取得內容長度
$req->getContentLength();

//Host   (e.g. "slimframework.com")
$req->getHost();

//Host with Port(e.g. "slimframework.com:80")
$req->getHostWithPort();

//Port  (e.g. 80)
$req->getPort();

//Scheme (e.g. "http" or "https")
$req->getScheme();

//Path (root URI + resource URI)
$req->getPath();

//URL (scheme + host [ + port if non-standard ])
$req->getUrl();

//IP Address
$req->getIp();

//Referer
$req->getReferrer();

//User Agent
$req->getUserAgent();

##Response Slim有一個用來回應使用者端的物件 - Response 可以控制headers, url status, body等相關狀態

$app = new \Slim\Slim();
$app->response;

設定狀態 可以自行設定HTTP回應狀態(例如 400, 500)

$app->response->setStatus(400);

也可以取得回應狀態

$status = $app->response->getStatus();

HEADER 例如,返回json值時,要將HEADERS Content-Type狀態設定為 application/json

<?php
$app = new \Slim\Slim();
$app->response->headers->set('Content-Type', 'application/json');

也可以取得HEADERS相關資訊

<?php
$contentType = $app->response->headers->get('Content-Type');

BODY HTTP返回訊息給使用者時,會夾帶body 可以透過response的setBody複寫或 write 增加 body 內容

<?php
$app = new \Slim\Slim();

// Overwrite response body
$app->response->setBody('Foo');

// Append response body
$app->response->write('Bar');

可以透過getBody取得內容

<?php
$body = $app->response->getBody();

##Render - 模板 Template view可以透過 render 來額外崁入模板,並且可以夾帶參數及HTTP狀態 模板預設位置在 templates/ (須自行建立資料夾)

<?php
$app = new \Slim\Slim();
$app->get('/',function() use ($app) {
  $app->render('show.php',array( 'name' => 'Josh' ));
});

新增模板 templates/show.php 在模板中取得資料的方式為 $this->data->[物件名稱]

//templates/show.php
<?php 
echo $this->data->name;//輸出 Josh

更改templates資料夾位置 透過templates.path參數可以設定

<?php 
require('vendor/autoload.php');
$app = new \Slim\Slim(array(
    'debug' => true,
    'templates.path' => 'tem'
));
/*//or this

$app = new \Slim\Slim(array(
    'debug' => true,
));
$app->config('templates.path', 'tem');
*/

$app->get('/',function() use ($app) {
  $view = $app->view();
  $app->render('show.php',array( 'name' => 'Josh' ));
});

夾帶HTTP狀態

<?php
$app->render(
    'myTemplate.php',
    array( 'name' => 'Josh' ),
    404
);

##自訂錯誤頁面

錯誤頁面 客製化錯誤處理頁面, 先在templates/資料夾中新增一個頁面(例如: error.html)

接著開始設定路由,只要發生錯誤,就自動導到新增的頁面

<?php
$app = new \Slim\Slim();
//發生錯誤
$app->error(function (\Exception $e) use ($app) {
    $app->render('error.php');
});
?>

404頁面 客製化404找不到頁面 先在templates/資料夾中新增頁面(例如: 404.html) 接著開始設定路由,當發生404找不到頁面錯誤時,就會自動導入404.html

另外,也可以單獨調用找不到頁面處理程序 只要呼叫 notFound()

<?php
$app = new \Slim\Slim();

$app->get('/hello/:name', function ($name) use ($app) {
    if ( $name === 'Waldo' ) {
        $app->notFound();
    } else {
        echo "Hello, $name";
    }
});

$app->notFound(function () use ($app) {
    $app->render('404.html');
    //echo '{"error":{"text":"not found"}}';
});
?>

##搭配PDO 連結資料庫 再使用PDO之前,要確定php.ini有啟用 php_pdo extension

先產生一個db.php,建立資料庫基本資訊 (這段用於說明,沒有防止sql injection)

//db.php
<?php
function getDB(){
  $dbhost='localhost';
  $dbuser='username';
  $dbpass='password';
  $dbname='database';
  $dbConnection = new PDO("mysql:host=$dbhost;dbname=$dbname;charset=utf8", $dbuser, $dbpass); 
  $dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  return $dbConnection;
}?>

在程式中include db.php

<?php 
require('db.php');
require('vendor/autoload.php');
$app = new \Slim\Slim();

$app->get('/',function() use ($app) {
   $sql = "SELECT id,name,phone FROM users ORDER BY name DESC";
   
   try {
        $db = getDB();
        $stmt = $db->query($sql); 
        $users = $stmt->fetchAll(PDO::FETCH_OBJ);
        $db = null;
        echo '{"users": ' . json_encode($users) . '}';
        //json格式會將中文編譯成unicode,可以print_r 看中文是否能正常顯示
        //print_r($users);
   } catch(PDOException $e) {
        echo '{"error":{"text":'. $e->getMessage() .'}}';
   }

});

##資料庫物件化 正式使用,可以將資料庫呼叫流程物件化 並且加入防止sql injection等防護

<?php
//db.php
class dbFn{

  function __construct(){
      $this->dbhost='localhost';
      $this->dbuser='root';
      $this->dbpass='xxxxxx';
      $this->dbname='slim_db';
  }

  public function getDB(){
    $dbConnection = new PDO("mysql:host=".$this->dbhost.";dbname=".$this->dbname.";charset=utf8", $this->dbuser, $this->dbpass); 
    //設置錯誤處理方式為 PDO::ERRMODE_EXCEPTION, PDO::ATTR_ERRMODE 拋出異常
    $dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    return $dbConnection;
  }

  //prevent sql injection
  function execute_($sql,$array=array()){
     try {
          $db = $this->getDb();
          $stmt = $db->prepare($sql); 
          $stmt->execute($array);
          $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
          unset($db);
          return $data;
     } catch(PDOException $e) {
          die('{"error":{"text":'. $e->getMessage() .'}}');
     }
  }

  //not prevent sql injection
  function query_($sql){
     try {
          $db = $this->getDb();
          $stmt = $db->query($sql); 
          $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
          unset($db);
          return $data;
     } catch(PDOException $e) {
          die('{"error":{"text":'. $e->getMessage() .'}}');
     }
  }
};
?>

於slim中呼叫資料庫物件

<?php 
require('db.php');
require('vendor/autoload.php');
$app = new \Slim\Slim(array(
    'debug' => true,
));

$app->get('/:name',function($name) use ($app) {
   $db = new dbFn();
   if($name!=''){
   		$sql = "SELECT id,name,phone FROM users WHERE name=:username ORDER BY name DESC";
   		$users = $db->execute_($sql,array('username'=>$name));
   }else{
      $sql = "SELECT id,name,phone FROM users ORDER BY name DESC";
   		$users = $db->execute_($sql);
   }

   echo '{"users": ' . json_encode($users) . '}';
});

jQuery取得json資料建議方式

<script type="text/javascript" src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
<script type="text/javascript">
$.getJSON( "網址", function( obj ) {
  $.each(obj['data'],function(i,v){
    console.log(v);
  });
});
</script>
</script>

#自動載入自定義Class composer 可以自行載入自己定義的Class 參考: http://phpenthusiast.com/blog/how-to-autoload-with-composer 先產生

your-website/
  src/
    Db.php

在src/Db.php資料夾中,建立namespace Acme 及 Db Class 由於在Db我們會用到 PDO 功能,因此要額外再 use \PDO

<?php 
namespace Acme;
use \PDO;

class Db{
  public function __construct()
  {
      define("SITE_KEY", "as+|fafjio%($");
  }

  function query_($sql){
     try {
          $db = $this->con();
          $stmt = $db->query($sql); 
          $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
          unset($db);
          return $data;
     } catch(PDOException $e) {
          die('{"error":{"text":'. $e->getMessage() .'}}');
     }
  }

  function query($sql){
     try {
          $db = $this->con();
          $stmt = $db->query($sql); 
          $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
          unset($db);
          return $data;
     } catch(PDOException $e) {
          die('{"error":{"text":'. $e->getMessage() .'}}');
     }
  }

  function query_excute($sql){
     try {
          $db = $this->con();
          $stmt = $db->query($sql); 
          // $stmt->execute();
          return $stmt;
     } catch(PDOException $e) {
          die('{"error":{"text":'. $e->getMessage() .'}}');
     }
  }

  function execute_data($sql,$array=array()){
     try {
          $db = $this->con();
          $stmt = $db->prepare($sql); 
          $stmt->execute($array);
          $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
          unset($db);
          $this->runData($data);
     } catch(PDOException $e) {
          die('{"error":{"text":'. $e->getMessage() .'}}');
     }
  }
  
  function execute_ary_data($sql,$array=array()){
   $result = array();
     try {
          $db = $this->con();
      
      foreach($sql as $k=>$v){
        $stmt = $db->prepare($v); 
        $stmt->execute($array);
        $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
        $result[] = $data;
      }
      
          unset($db);
          $this->runData($result);
     } catch(PDOException $e) {
          die('{"error":{"text":'. $e->getMessage() .'}}');
     }
    
  }

  function execute_($sql,$array=array()){
     try {
          $db = $this->con();
          $stmt = $db->prepare($sql); 
          $stmt->execute($array);
          $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
          unset($db);
          return $data;
     } catch(PDOException $e) {
          die('{"error":{"text":'. $e->getMessage() .'}}');
     }
  }

  function runData($data){
    echo '{"data": ' . json_encode($data) . '}';
  }

  private function con(){
    $dbConnection = new PDO("mysql:host=".dbhost.";dbname=".dbname.";charset=".dbcharset, dbuser, dbpws);
    $dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    return $dbConnection;
  }

}; 

設定 composer.json

{
    "require": {
        "slim/slim": "~2.0"
    },
    "autoload": {
      "psr-4": {
        "Acme\\":"src/"
      }
    }
}

打開終端機,更新 Composer autoloader

 composer dumpautoload -o

接下來,可以在檔案中使用這個空間命名的方式呼叫Class

<?php session_start();
require('..\include\config.php');
require('vendor\autoload.php');
use Acme\Db;
$app = new \Slim\Slim(array('debug' => true));
$Db = new Db();
...
$app->notFound(function () use ($app) { echo '{"error":{"text":"not found"}}'; });
$app->run();
?>

如果在這頁,將API放在外,會使用到Db功能,以include的方式引用 use Acme\Db; 則需放在API那頁

<?php session_start();
require('..\include\config.php');
require('vendor\autoload.php');
$app = new \Slim\Slim(array('debug' => true));
require('ctrl\index.php');
$app->notFound(function () use ($app) { echo '{"error":{"text":"not found"}}'; });
$app->run();
?>
<?php
use Acme\Db;

define('shopID',1);
define('MobileUserID','adam');


$app->post('/login_check/', function() use ($app){
  print_r($console_user_login_err);
  echo 'adsf';
  die();
      $id = $app->request->post('id');
      $password = $app->request->post('password');
      $db = new Db();
      $r = $db->execute_("call console_user_login(:id, :pw, :from)", array('id'=>$id, 'pw'=>sha1($password), 'from'=>$_SERVER['REMOTE_ADDR']));
      if($r==false) {
        die('{"error":{"text":"Please check id or password!"}}');
      }else if($r[0]['result(0=success)']!=0){
        $result = $r[0]['result(0=success)'];
        die('{"error":{"text":"'.$console_user_login_err[$result].'"}}');
      }else{
        die('{"msg":{"text":1}}');
      }

});

Login and Logout

https://github.com/briannesbitt/Slim-ContextSensitiveLoginLogout