SlideShare a Scribd company logo
1 of 124
Download to read offline
范聖佑 (Shengyou Fan)
Modern Web 2016
2016/08/24
讓你的 PHP 開發流程
再次潮起來!
{	
  
	
  	
  	
  	
  "name":	
  "shengyou/self-­‐introduction",	
  
	
  	
  	
  	
  "description":	
  "個⼈人簡介",	
  
	
  	
  	
  	
  "authors":	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "name":	
  "范聖佑	
  (Shengyou	
  Fan)",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "email":	
  "shengyoufan@gmail.com",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "homepage":	
  "http://www.shengyoufan.com",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "company":	
  "得寬科技	
  (The	
  Qwan)",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "role":	
  ["研究員",	
  "Laravel	
  傳教⼠士"]	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  ],	
  
	
  	
  	
  	
  "support":	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  "facebook":	
  "http://fb.me/shengyoufan",	
  
	
  	
  	
  	
  	
  	
  	
  	
  "twitter":	
  "@shengyou",	
  
	
  	
  	
  	
  }	
  
}
v2.2 v4.0	
  ~	
  v5.2
Page Script
5.3
探索歷程
Laravel 台灣
https://www.facebook.com/groups/laravel.tw
成⽴立於 2013 現有 4000 位成員加⼊入
Laravel 道場
http://www.laravel-dojo.com
致⼒力於提供最好的 Laravel 教育訓練
2016.03
正修科⼤大資⼯工系
2016.01
中華電信學院
2015.07
新北市樹林國⼩小
2014.12
彰師⼤大資⼯工系
2015.05
臺中科⼤大資⼯工系
2015.12
⻁虎尾科⼤大電算中⼼心
2016.02
交通⼤大學資服中⼼心
2016.07
逢甲⼤大學⿊黑客社
2016.08
勤益科⼤大電算中⼼心
★
持續推廣中!
推廣了三年,
最常聽到的回應是…
Laravel 好棒!
但我們公司
沒辦法導⼊入…
我們還在⽤用舊版 PHP
歷史包衭、升級有難度
因為…
絕⼤大部份的程式碼都是 Page Script
產品流程複雜、維護⼯工作多
打掉重練不可能
上線已久、使⽤用者固定
⽽而且…它賺錢!
因為…
我很有興趣
對團隊⽂文化及導⼊入成本的疑慮
但我的主管和同事…
因為…
⽽而且我⽼老闆覺得…
• 先改善效益最⼤大的地⽅方
• ⼀一次改變⼀一點不要太多
• 每⼀一步都不會太難
• 讓成員感受到好處
• ⾃自然⽽而然慢慢習慣
⾝身為傳教⼠士的反思
六個可獨⽴立推⾏行的施⼒力點
優化
環境建置流程
升級
開發⼯工具
導⼊入
Composer
導⼊入
Migration
導⼊入
適⽤用框架
導⼊入
⾃自動化
視團隊可以導⼊入的點,⼀一次施⼒力⼀一點點
優化環境建置流程
依賴網路與測試機的開發
Mac Windows Linux
測試主機 測試資料庫
優化⽅方向
• 以本地端可以獨⽴立運作開發為⺫⽬目標
- 不需依賴開發機、網路,可單兵作業
- 在地端開發但⼜又不影響本機環境
各出奇招的開發環境
Mac Windows Linux
優化⽅方向
• 新/舊專案依需求和現況使⽤用不同的 PHP 版本
• 從作業系統到 PHP 各專案完全獨⽴立
• 開發時的環境就是上線時的環境
- 降低任何因環境不同⽽而可能出現的錯誤
新成員加⼊入專案時
• 先看專案 README
• 試著了解專案所需的環境
• 開始安裝
• 遭遇錯誤 → 解決 → 遭遇錯誤 → 解決
• 開始貢獻
(前提是有 README)
有新成員時就再循環⼀一次…
優化⽅方向
• 降低新成員進⼊入專案時的⾨門檻
- 讓成員可以專注在⾃自⼰己的貢獻上
• 減少建置時所需花費的時間成本
- 縮短成員融⼊入專案的時間
VirtualBox +Vagrant
Mac Windows Linux
Vagrant	
  Box Vagrant	
  Box Vagrant	
  Box
選定作業系統
https://atlas.hashicorp.com/boxes/search
下載 Box 並初始化
$	
  vagrant	
  box	
  add	
  {box	
  name}	
  
$	
  vagrant	
  init	
  {box	
  name}
Vagrantfile
Vagrant.configure(2)	
  do	
  |config|	
  
	
  	
  config.vm.box	
  =	
  "ubuntu/trusty64"	
  
	
  	
  config.vm.provider	
  "virtualbox"	
  do	
  |vb|	
  
	
  	
  	
  	
  vb.customize	
  ["modifyvm",	
  :id,	
  "-­‐-­‐memory",	
  "512"]	
  
	
  	
  	
  	
  vb.customize	
  ["modifyvm",	
  :id,	
  "-­‐-­‐cpus",	
  "1"]	
  
	
  	
  	
  	
  vb.customize	
  ["modifyvm",	
  :id,	
  "-­‐-­‐natdnsproxy1",	
  "on"]	
  
	
  	
  	
  	
  vb.customize	
  ["modifyvm",	
  :id,	
  "-­‐-­‐natdnshostresolver1",	
  "on"]	
  
	
  	
  end	
  
	
  	
  config.vm.network	
  "forwarded_port",	
  guest:	
  80,	
  host:	
  8080	
  
	
  	
  config.vm.network	
  "private_network",	
  ip:	
  "192.168.10.10"	
  
end
啟動VM
$	
  vagrant	
  up
模擬多主機環境
Vagrant.configure(2)	
  do	
  |config|	
  
	
  	
  config.vm.define	
  :app	
  do	
  |app|	
  
	
  	
  	
  	
  app.vm.box	
  =	
  "ubuntu/trusty64"	
  
	
  	
  	
  	
  #	
  ...	
  
	
  	
  	
  	
  app.vm.network	
  "private_network",	
  ip:	
  "192.168.10.10"	
  
	
  	
  end	
  
	
  	
  config.vm.define	
  :db	
  do	
  |db|	
  
	
  	
  	
  	
  db.vm.box	
  =	
  "ubuntu/trusty64"	
  
	
  	
  	
  	
  #	
  ...	
  
	
  	
  	
  	
  db.vm.network	
  "private_network",	
  ip:	
  "192.168.10.11"	
  
	
  	
  end	
  
end
登⼊入各別主機
$	
  vagrant	
  ssh	
  {machine}
$	
  vagrant	
  ssh	
  app $	
  vagrant	
  ssh	
  db
客製化需求
#	
  VM	
  外	
  
$	
  vagrant	
  ssh	
  
#	
  VM	
  裡	
  
$	
  apt-­‐get	
  install	
  ...	
  
$	
  exit	
  
#	
  VM	
  外	
  
$	
  vagrant	
  package	
  
$	
  vagrant	
  box	
  add	
  {box	
  name}	
  package.box
#	
  在專案資料夾內	
  
$	
  vagrant	
  init	
  {box	
  name}	
  
$	
  vagrant	
  up
1. 先客製化 Box 2. ⽤用客製化 Box 開機器
Homestead
• Laravel 官⽅方使⽤用VitrualBox 及Vagrant 技術製作出來的
VM Box
• 可以迅速在本機上建置開發 Laravel 所需的多合⼀一環境
• 不僅可以拿來開發 Laravel,拿來開發其他 PHP 專案也
是可以的!
• 套件新、更新勤、抽換快!
Homestead 操作流程
#	
  下載	
  Homestead	
  
$	
  git	
  clone	
  ...homestead.git	
  Homestead	
  
$	
  cd	
  Homestead	
  
$	
  bash	
  init.sh	
  	
  
#	
  設定	
  Homestead	
  
$	
  vim	
  ~/.homestead/Homestead.yaml	
  
folders:	
  
	
  	
  	
  	
  -­‐	
  map:	
  {本機資料夾}	
  
	
  	
  	
  	
  	
  	
  to:	
  {VM	
  內資料夾}	
  
sites:	
  	
  
	
  	
  	
  	
  -­‐	
  map:	
  {開發⽤用網址}	
  
	
  	
  	
  	
  	
  	
  to:	
  {VM	
  內網站根⺫⽬目錄}
#	
  設定	
  Host	
  
$	
  vim	
  /path/to/hosts	
  
#	
  啟動	
  Homestead	
  
$	
  vagrant	
  up
客製化 Homestead
#!/bin/sh	
  
if	
  [	
  !	
  -­‐f	
  /usr/local/extra_homestead_software_installed	
  ];	
  then	
  
	
  	
  echo	
  "installing	
  some	
  extra	
  software"	
  
	
  	
  sudo	
  -­‐s	
  	
  
	
  	
  apt-­‐get	
  install	
  -­‐y	
  ...	
  
	
  	
  touch	
  /usr/local/extra_homestead_software_installed	
  
else	
  	
  	
  	
  	
  
	
  	
  echo	
  "extra	
  software	
  already	
  installed...	
  moving	
  on..."	
  
fi
$	
  vim	
  ~/.homestead/after.sh
不能⽤用VM 的特殊狀況…
• Laravel 道場 拿來做教學的訓練機
• 整合 Cmder、UwAmp、git、Composer
等多項開放源始碼⼯工具於⼀一體
• 獨⽴立的環境變數、port 設定
• 免安裝、免設定、解壓縮即可使⽤用!
• 在會重開機⾃自動還原的環境下特別好⽤用!
⺫⽬目前正式發佈 v1.3.0 穩定版
http://www.laravel-dojo.com/opensource/wagon
wagon 懶⼈人包
升級開發⼯工具
總是有千萬個原因…
所以程式碼還沒有版本管理…
git 也是有 GUI 的
https://www.gitkraken.com/https://www.sourcetreeapp.com
git 也是可以接 svn 的
#	
  把	
  svn	
  裡的檔案取出來	
  
$	
  git	
  svn	
  clone	
  -­‐r	
  HEAD	
  {SVNSERVER}	
  {folder}	
  
#	
  git	
  ⽇日常指令	
  
$	
  cd	
  {folder}	
  
$	
  vim	
  {file}	
  
$	
  git	
  add	
  {file}	
  
$	
  git	
  commit	
  -­‐a	
  -­‐m	
  '{message}'	
  
#	
  同步到	
  svn	
  上	
  
$	
  git	
  svn	
  rebase	
  
$	
  git	
  svn	
  dcommit
git 也是可以⽤用 FTP 部署的
https://ftploy.com/https://git-­‐ftp.github.io/
不是不願意⽤用好的編輯器,
⽽而是壓根兒不知道有好的編輯器!
常⾒見錯誤
幼幼班 初級班 進階班
• 沒存檔
• 漏分號 ;
• 漏其符號 ,	
  '	
  "
• 括號	
  {	
  [	
  (	
  沒
成對或範圍錯誤
• 基本 PHP 語法錯
誤
• 物件沒實體化就
使⽤用
• 沒有⽤用 use (漏
namespace)
• 重覆的 function
名稱
• undefine function
• 沒有 return 或
return 的型別不
對
• 重複的邏輯
• Interface 定義了
但忘了實作
更多補助
• 語法⾼高亮度
• 語法檢查
• 語法提⽰示
• 程式碼⽚片段
• 程式碼⾵風格統⼀一
• 與版本管理系統整合
• 程式重構
⼯工具選⽤用
PhpStorm Visual	
  Studio	
  Code
EditorIDE
不⽤用 breakpoint 來偵錯?
這哪叫 debug?
- 點燈坊 Oomusou
http://oomusou.io/
除錯⼯工具
• ⼟土炮式掃雷
- echo (!) → exit
- var_dump() → exit
- print_r() → exit
• Laravel 式除錯
- dd() (底層為 SymfonyVarDumper)
編輯器 + XDebug
https://youtu.be/7Jwj2L51JaA
導⼊入 Composer
寧可把時間拿去玩寶可夢,
也不要花時間重造輪⼦子!
永遠扯不清的 include 地獄
//	
  需要⽤用到	
  lib1	
  裡的	
  Class	
  
include	
  __DIR__	
  .	
  "/libs/lib1/Class.php";	
  
//	
  lib1	
  相依於	
  lib2	
  及	
  lib3	
  
include	
  __DIR__	
  .	
  "/libs/lib2/Class.php";	
  
include	
  __DIR__	
  .	
  "/libs/lib3/Class.php";	
  
//	
  lib2	
  相依於	
  lib4	
  
include	
  __DIR__	
  .	
  "/libs/lib4/Class.php";	
  
//	
  lib3	
  相依於	
  lib999	
  
include	
  __DIR__	
  .	
  "/libs/lib999/Class.php";
寫 new 寫得提⼼心吊膽
//	
  實體化	
  Class	
  
$class	
  =	
  new	
  MyClass();	
  
//	
  載⼊入	
  Class	
  失敗	
  
PHP	
  Fatal	
  error:	
  	
  Class	
  'MyClass'	
  not	
  found	
  in	
  scripts.php	
  
on	
  line	
  x
優化⽅方向
• 不再落⼊入 include / require 地獄
- 解決裝 A 掉 B 少 C 的困境
• ⾃自動載⼊入專案內的 類別 / 函式
- 使⽤用類別時不⽤用⼿手動 include
- 使⽤用⾃自定函式不⽤用⼿手動 include
⼿手動管理專案套件庫
libs/
函式庫
函式庫 B
函式庫 C
函式庫 函式庫 E
移除
新增
函式庫 函式庫 D
置換
函式庫 A
更新
v.2v.1
優化⽅方向
• 以專案為基礎的套件管理機制
- 各專案內的套件獨⽴立管理,不互相影響
• ⾃自動化下載、更新套件
- 統⼀一的套件版本管理機制
- 流程由⾃自動化⼯工具輔助
• 加⼊入 PHP 的套件⽣生態系
- 不再重新發明輪⼦子
Composer 套件管理
composer.phar
執⾏行檔
+ +
git
版本控制
php 5.3.2
(openssl extension)
安裝 Composer
#	
  下載安裝指令	
  (請使⽤用官網完整指令)	
  
$	
  php	
  -­‐r	
  "copy('https://getcomposer.org/installer',	
  ...);"	
  
$	
  php	
  -­‐r	
  "..."	
  
$	
  php	
  composer-­‐setup.php	
  
$	
  php	
  -­‐r	
  "unlink('composer-­‐setup.php');"	
  
#	
  將	
  Composer	
  變成系統全域指令	
  
$	
  mv	
  composer.phar	
  /usr/local/bin/composer	
  
#	
  使⽤用	
  Composer	
  
$	
  [php]	
  composer[.phar]	
  {command}
https://getcomposer.org/download/	
  
增加 composer.json
{	
  
	
  	
  	
  	
  "name":	
  "{vendor}/{project}",	
  
	
  	
  	
  	
  "type":	
  "project",	
  
	
  	
  	
  	
  "license":	
  "proprietary",	
  
	
  	
  	
  	
  "authors":	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "name":	
  "{author	
  name}",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "email":	
  "{author	
  email}"	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  ],	
  
	
  	
  	
  	
  "minimum-­‐stability":	
  "stable",	
  
	
  	
  	
  	
  "require":	
  {}	
  
}
$	
  composer	
  init
軍⽕火庫
https://packagist.org
安裝/更新套件
$	
  composer	
  require	
  {vendor}/{project}	
  
$	
  composer	
  [install|update]
⾃自動載⼊入設定
<?php	
  
require	
  __DIR__	
  .	
  '/vendor/autoload.php';
從此只需要寫的	
  require
套件⽣生態系
https://github.com/ziadoz/awesome-­‐php
nesbot/carbon
<?php	
  
require	
  __DIR__	
  .	
  '/vendor/autoload.php';	
  
//	
  像	
  Facebook	
  ⼀一樣顯⽰示時間間距	
  
use	
  CarbonCarbon;	
  
$past	
  =	
  Carbon::yesterday()	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>addHours(4)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>minute(30);	
  
Carbon::setLocale('zh-­‐TW');	
  
echo	
  $past-­‐>diffForHumans(Carbon::now());	
  //	
  ⼀一天前
intervention/image
<?php	
  
require	
  __DIR__	
  .	
  '/vendor/autoload.php';	
  
//	
  處理圖⽚片縮⼩小轉存	
  
use	
  InterventionImageImageManagerStatic	
  as	
  Image;	
  
Image::configure(array('driver'	
  =>	
  'imagick'));	
  
$image	
  =	
  Image::make('public/foo.jpg')	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>resize(300,	
  200)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>save('public/bar.png',	
  60);
recca0120/laravel-­‐tracy
<?php	
  
require	
  __DIR__	
  .	
  '/vendor/autoload.php';	
  
use	
  Recca0120LaravelTracyTracy;	
  
Tracy::instance();
除錯畫⾯面及⾯面板
//	
  tracy.php	
  
<?php	
  
$config	
  =	
  [	
  
	
  	
  	
  	
  'enabled'	
  =>	
  true,	
  
	
  	
  	
  	
  'showBar'	
  =>	
  true,	
  
	
  	
  	
  	
  'accepts'	
  =>	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  'text/html',	
  
	
  	
  	
  	
  ],	
  
	
  	
  	
  	
  'editor'	
  =>	
  'vscode://open?url=file://%file&line=%line',	
  
	
  	
  	
  	
  'panels'	
  =>	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  '{name}'	
  =>	
  {boolean},	
  
	
  	
  	
  	
  ],	
  
];
VS Code URL Handler
https://github.com/shengyou/vscode-­‐handler
截錯、開檔⼀一鍵完成!
https://youtu.be/sxASikzX-­‐gc
先別管 Packagist 上的套件了,
你知道 Composer 也可以幫你載⼊入你
的類別和函式嗎?
三⼤大⾃自動載⼊入⽅方式
{	
  
	
  	
  	
  	
  "autoload":	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  "psr-­‐4":	
  {...},	
  
	
  	
  	
  	
  	
  	
  	
  	
  "classmap":	
  [...],	
  
	
  	
  	
  	
  	
  	
  	
  	
  "files":	
  [...]	
  
	
  	
  	
  	
  },	
  
	
  	
  	
  	
  "autoload-­‐dev":	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  "psr-­‐4":	
  {...},	
  
	
  	
  	
  	
  	
  	
  	
  	
  "classmap":	
  [...],	
  
	
  	
  	
  	
  	
  	
  	
  	
  "files":	
  [...]	
  
	
  	
  	
  	
  },	
  
}
$	
  vim	
  composer.json
以 psr-­‐4 載⼊入
{	
  
	
  	
  	
  	
  "autoload":	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  "psr-­‐4":	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "App":	
  "app/"	
  
	
  	
  	
  	
  	
  	
  	
  	
  },	
  
	
  	
  	
  	
  }	
  
}
$	
  composer	
  dump-­‐autoload
//	
  app/MyAwesomeClass.php	
  
namespace	
  App;	
  
class	
  MyAwesomeClass	
  extends	
  SuperPower	
  
{	
  
	
  	
  	
  	
  //	
  ...	
  
}
MyAwesomeClass.php
app
composer.json
//	
  index.php	
  
<?php	
  
require	
  __DIR__	
  .	
  '/vendor/autoload.php';	
  
use	
  AppMyAwesomeClass;	
  
$awesomeness	
  =	
  new	
  MyAwesomeClass();	
  
?>
autoload.php
vendor
index.php
以 classmap 載⼊入
$	
  composer	
  dump-­‐autoload
{	
  
	
  	
  	
  	
  "autoload":	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  "classmap":	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "libs"	
  
	
  	
  	
  	
  	
  	
  	
  	
  ],	
  
	
  	
  	
  	
  }	
  
}
composer.json
autoload.php
vendor
index.php
libs
my-­‐old-­‐school-­‐class.php
//	
  classes/my-­‐old-­‐school-­‐class.php	
  
class	
  my_old_school_class	
  
{	
  
	
  	
  	
  	
  //	
  ...	
  
}
//	
  index.php	
  
<?php	
  
require	
  __DIR__	
  .	
  '/vendor/autoload.php';	
  
$oldschool	
  =	
  new	
  my_old_school_class();	
  
?>
以 files 載⼊入
$	
  composer	
  dump-­‐autoload
{	
  
	
  	
  	
  	
  "autoload":	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  "files":	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "helpers/my-­‐functions.php"	
  
	
  	
  	
  	
  	
  	
  	
  	
  },	
  
	
  	
  	
  	
  }	
  
}
//	
  helpers/my_functions.php	
  
<?php	
  
if	
  (!	
  function_exists('super_power'))	
  {	
  
	
  	
  	
  	
  function	
  super_power()	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  //...	
  
	
  	
  	
  	
  }	
  
}
//	
  index.php	
  
<?php	
  
require	
  __DIR__	
  .	
  '/vendor/autoload.php';	
  
?>	
  
<!-­‐-­‐	
  ...	
  -­‐-­‐>	
  
	
  	
  	
  	
  <h1><?php	
  super_power()	
  ?></h1>	
  
<!-­‐-­‐	
  ...	
  -­‐-­‐>
my_functions.php
helpers
composer.json
autoload.php
vendor
index.php
團隊/公司內的私有套件也可以⽤用
Composer 管理嗎?
當然可以!
建⽴立私有套件
#	
  建⽴立專案⺫⽬目錄	
  
$	
  mkdir	
  secret-­‐ingredient	
  
$	
  cd	
  secret-­‐ingredient	
  
$	
  git	
  init	
  
$	
  composer	
  init	
  
$	
  composer	
  install	
  
#	
  撰寫套件程式碼	
  
$	
  vim	
  ...	
  
$	
  git	
  commit	
  ...	
  
#	
  設定套件版本並發佈	
  
$	
  git	
  tag	
  -­‐a	
  1.0	
  
$	
  git	
  push	
  ...
設定 Repositories
{	
  
	
  	
  	
  	
  "require":	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  "{vendor}/{project}":	
  "{version}"	
  
	
  	
  	
  	
  },	
  
	
  	
  	
  	
  "repositories":	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "type":	
  "vcs",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "url":	
  "{url}"	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  ],	
  
}
$	
  composer	
  update
套件資訊庫 / Proxy
https://toranproxy.com/https://github.com/composer/satis
導⼊入 Migration
共同 DB 開發的問題
成員間 DB 共⽤用,A 改 B 壞 C 等
資料庫結構同步的問題
成員間 DB 不同步,A 改 B 壞 C 等
不是每個團隊都有 DBA,
如何讓資料庫也有版本管理的功能?
優化⽅方向
• 導⼊入 Migration ⼯工具
- 透過撰寫程式碼的⽅方式紀錄資料庫異動
- 部份⼯工具也有 Seeding 的設計,輕鬆產⽣生測試資料
- 部份⼯工具也有對應的 ORM,可⼀一併處理 Model
Laravel 的 Migration
$	
  artisan	
  make:migration	
  {name}
//	
  database/migrations/{migration}.php	
  
public	
  function	
  up()	
  
{	
  
	
   Schema::{create|table}('{table}',	
  function	
  (Blueprint	
  $table)	
  {	
  
	
   	
   $table-­‐>increments('id');	
  
	
   	
   	
  
	
   	
   $table-­‐>{column	
  type}('{column	
  name}');	
  
	
   	
   	
  
	
   	
   $table-­‐>timestamps();	
  
	
   });	
  
}
資料庫變更回溯
//	
  database/migrations/{migration}.php	
  
public	
  function	
  down()	
  
{	
  
	
  	
  	
  	
  //	
  寫跟	
  up()	
  反向的動作	
  
	
  	
  	
  	
  Schema::drop('{table}');	
  
	
  	
  	
  	
  Schema::table('{table}',	
  function	
  (Blueprint	
  $table)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  $table-­‐>dropColumn('{column}');	
  
	
  	
  	
  	
  });	
  
}
$	
  artisan	
  migrate	
  
$	
  artisan	
  migrate:rollback
填充測試資料
$	
  artisan	
  make:seeder	
  {name}	
  
$	
  artisan	
  db:seed
//	
  database/seeds/{seeder}.php	
  
public	
  function	
  run()	
  
{	
  
	
  	
  	
  	
  {Model}::truncate();	
  
	
  	
  	
  	
  foreach(range(1,	
  10)	
  as	
  $number)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  {Model}::create([	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  '{column}'	
  =>	
  '{value}',	
  
	
  	
  	
  	
  	
  	
  	
  ]);	
  
	
  	
  	
  	
  }	
  
}
不想⽤用 Laravel 的話也有解嗎?
不⽤用 Laravel 時的選擇
Phinx Lazy	
  Record Propel	
  Orm
Phinx
$	
  composer	
  require	
  robmorgan/phinx	
  
$	
  vendor/bin/phinx	
  init
///	
  phinx.yml	
  
paths:	
  
	
  	
  	
  	
  migrations:	
  %%PHINX_CONFIG_DIR%%/db/migrations	
  
	
  	
  	
  	
  seeds:	
  %%PHINX_CONFIG_DIR%%/db/seeds	
  
environments:	
  
	
  	
  	
  	
  default_migration_table:	
  phinxlog	
  
	
  	
  	
  	
  default_database:	
  development	
  
	
  	
  	
  	
  production:	
  #	
  ...	
  
	
  	
  	
  	
  development:	
  #	
  ...	
  
	
  	
  	
  	
  testing:	
  #	
  ...
Phinx Migration
$	
  vendor/bin/phinx	
  create	
  {name}	
  
$	
  vendor/bin/phinx	
  migrate	
  
$	
  vendor/bin/phinx	
  rollback
//	
  db/migrations/{migration}.php	
  
public	
  function	
  change()	
  
{	
  
	
  	
  	
  	
  $table	
  =	
  $this-­‐>table('{name}');	
  
	
   	
  
	
  	
  	
  	
  $table-­‐>addColumn('{column}',	
  '{data	
  type}')	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐>create();	
  
}
Phinx Seeding
$	
  vendor/bin/phinx	
  seed:create	
  {name}	
  
$	
  vendor/bin/phinx	
  seed:run
///	
  db/seeds/{seeder}.php	
  
public	
  function	
  run()	
  
{	
   	
  
	
  	
  	
  	
  $data	
  =	
  [];	
  	
  
	
  	
  	
  	
  foreach(range(1,	
  10)	
  as	
  $number)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  $data[]	
  =	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  ...	
  
	
  	
  	
  	
  	
  	
  	
  	
  ];	
  
	
  	
  	
  	
  }	
  
	
   	
  
	
  	
  	
  	
  $this-­‐>insert('{table}',	
  $data);	
  
}
導⼊入適⽤用框架
先問你想解決什麼問題?
再來討論要怎麼解決。
哪⼀一種適合專案需求?
開發敏捷 穩定⾼高效能
努⼒力了這麼久…
總算可以試著導⼊入了!
導⼊入之前
PHP ⾄至少先升到 5.5.9 以
上 (Laravel 5.2 最低需求)
專案已導⼊入 Composer,
專案內的類別已經完成
autloading 的設定
導⼊入進程
相容現有資料庫 新舊版共容 更換套件 相容舊有網址
先從資料庫開始
只要 PDO ⽀支援的都可以!
//	
  config/database.php	
  
return	
  [	
  
	
  	
  	
  	
  'default'	
  =>	
  '{connection}',	
  
	
  	
  	
  	
  'connections'	
  =>	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  'sqlite'	
  =>	
  [/*	
  ...	
  */],	
  
	
  	
  	
  	
  	
  	
  	
  	
  'mysql'	
  	
  =>	
  [/*	
  ...	
  */],	
  
	
  	
  	
  	
  	
  	
  	
  	
  'pgsql'	
  	
  =>	
  [/*	
  ...	
  */],	
  
	
  	
  	
  	
  	
  	
  	
  	
  'sqlsrv'	
  =>	
  [/*	
  ...	
  */],	
  
	
  	
  	
  	
  ],	
  
];
原⽣生不⽀支援的,也有 Package
https://github.com/yajra/laravel-­‐oci8http://php.net/oci8
最新流⾏行的,也有 Package
https://github.com/jenssegers/laravel-­‐mongodb
時下流⾏行的也有 Package 可⽤用
反轉 DB 結構成 Migration/Seed
• 將現有 DB 結構反轉成 Migration
- https://github.com/Xethron/migrations-generator
- https://github.com/nWidart/DbExporter
- https://gist.github.com/bruceoutdoors/9166186
• 將現有 DB 資料反轉成 Seed
- https://github.com/orangehill/iseed
P.S 無法完美轉換,尤其是 Relation 的部份,建議轉出來後⼿手動調整
讓 Eloquent 相容現有 DB
class	
  ExisteingDbModel	
  extends	
  Model	
  
{	
  
	
  	
  	
  	
  //	
  指定使⽤用的	
  DB	
  (依照	
  config/database.php	
  的設定	
  
	
  	
  	
  	
  protected	
  $connection	
  =	
  '{connection}';	
  
	
  	
  	
  	
  //	
  指定	
  Model	
  對應的	
  table	
  
	
  	
  	
  	
  protected	
  $table	
  =	
  '{table}';	
  
	
  	
  	
  	
  //	
  指定	
  table	
  內的主鍵	
  
	
  	
  	
  	
  protected	
  $primaryKey	
  =	
  '{column}';	
  
}
設定 column 預設值及型別
class	
  ExisteingDbModel	
  extends	
  Model	
  
{	
  
	
  	
  	
  	
  protected	
  $attributes	
  =	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  '{column}'	
  =>	
  {value},	
  
	
  	
  	
  	
  ];	
  
	
  	
  	
  	
  protected	
  $cast	
  =	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  '{column}'	
  =>	
  '{data	
  type}',	
  
	
  	
  	
  	
  ];	
  
}
讓 Eloquent 轉換 column 名稱
class	
  ExisteingDbModel	
  extends	
  Model	
  
{	
  
	
  	
  	
  	
  //	
  Accessors	
  
	
  	
  	
  	
  public	
  function	
  get{Column}Attribute()	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  return	
  $this-­‐>attributes['{column}'];	
  
	
  	
  	
  	
  }	
  
	
  	
  	
  	
  //	
  Mutators	
  
	
  	
  	
  	
  public	
  function	
  set{Column}Attribute($value)	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  $this-­‐>attributes['{column}']	
  =	
  $value;	
  
	
  	
  	
  	
  }	
  
}
相容⽇日期/時間的 column
class	
  ExisteingDbModel	
  extends	
  Model	
  
{	
  
	
  	
  	
  	
  //	
  設定需要轉換為	
  date/time	
  的	
  column	
  
	
  	
  	
  	
  protected	
  $dates	
  =	
  ['{column}'];	
  
	
  	
  	
  	
  //	
  設定	
  DB	
  內⽇日期時間格式	
  
	
  	
  	
  	
  protected	
  $dateFormat	
  =	
  '{format}';	
  
	
  	
  	
  	
  //	
  設定	
  created_at	
  及	
  updated_at	
  對應到的	
  column	
  
	
  	
  	
  	
  const	
  CREATED_AT	
  =	
  'created_at';	
  
	
  	
  	
  	
  const	
  UPDATED_AT	
  =	
  'updated_at';	
  
	
  	
  	
  	
  //	
  設定	
  Eloquent	
  是否啟動	
  created_at	
  及	
  updated_at	
  
	
  	
  	
  	
  public	
  $timestamps	
  =	
  {boolean};	
  
}
新/舊版網站共存
• 先在新版 (Laravel 版) 實作⾸首⾴頁,取代 index.php
- 更換 HTTP 伺服器的 Document Root
• 把舊版 (Page Script 版) 的前台網站直接放到 Laravel 專案
的 public 資料夾裡
- HTTP 伺服器優先使⽤用已經存在實體檔案的 Page Script
P.S	
  也可以視情況使⽤用	
  symbolic	
  link	
  讓新/舊版共存
$	
  ln	
  -­‐s	
  path/to/page-­‐script-­‐ver	
  path/to/laravel/public
先重做後台
//	
  設定	
  app/Http/routes.php	
  
//	
  把後台放到前置詞底下	
  
Route::group(['prefix'	
  =>	
  'admin'],	
  function()	
  {	
  
	
  	
  	
  	
  //	
  實際上的	
  URL	
  會是	
  "/admin/{uri}"	
  
	
  	
  	
  	
  Route::get('{uri}',	
  [/*	
  ...	
  */]);	
  
});	
  
//	
  把後台放到	
  sub-­‐domain	
  去	
  
Route::group(['domain'	
  =>	
  '{domain	
  name}'],	
  function()	
  {	
  
	
  	
  	
  	
  //	
  在	
  {domain	
  name}	
  底下才有辦法看到此	
  Route	
  
	
  	
  	
  	
  Route::get('{uri}',	
  [/*	
  ...	
  */]);	
  
});
抽換功能改⽤用套件⽣生態系
• Laravel 已經有做的功能就不要⾃自⼰己再重做⼀一次
- Route、MVC、Mail、Template Engine、Cron
• Laravel 沒有的功能也先找有沒有套件已經做過
- https://github.com/chiraggude/awesome-laravel
- https://github.com/summerblue/laravel-package-top-100
使⽤用 Route 處理舊版網址
//	
  app/Http/routes.php	
  
Route::get('{all}',	
  [/*	
  ...	
  */])	
  
	
  	
  	
  	
  	
  -­‐>where('all',	
  '.*');	
  
//	
  app/Http/Controllers/SeoController.php	
  
class	
  SeoController	
  extends	
  Controller	
  
{	
  
	
  	
  	
  	
  public	
  function	
  reroute($uri)	
  
	
  	
  	
  	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  //	
  ...	
  
	
  	
  	
  	
  	
  	
  	
  	
  return	
  redirect('{uri}',	
  301);	
  
	
  	
  	
  	
  }	
  
}
專案就是不能導⼊入…
但⼜又很想⽤用 Laravel 的語法?
置⼊入性 Programming
只要能⽤用	
  Composer	
  裝得都好說!
{	
  
	
  	
  	
  	
  "require":	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  "php":	
  ">=5.5.9",	
  
	
  	
  	
  	
  	
  	
  	
  	
  "illuminate/view":	
  "^5.2",	
  
	
  	
  	
  	
  	
  	
  	
  	
  "illuminate/database":	
  "^5.2",	
  
	
  	
  	
  	
  	
  	
  	
  	
  "illuminate/events":	
  "^5.2",	
  
	
  	
  	
  	
  	
  	
  	
  	
  "illuminate/pagination":	
  "^5.2",	
  
	
  	
  	
  	
  	
  	
  	
  	
  "illuminate/http":	
  "^5.2",	
  
	
  	
  	
  	
  	
  	
  	
  	
  "recca0120/laravel-­‐tracy":	
  "^1.5"	
  
	
  	
  	
  	
  }	
  
}
載⼊入 Laravel 元件
//	
  bootstrap.php	
  
use	
  IlluminateDatabaseCapsuleManager	
  as	
  Capsule;	
  
$capsule	
  =	
  new	
  Capsule;	
  
$capsule-­‐>addConnection([	
  
	
  	
  	
  	
  'driver'	
  	
  	
  	
  =>	
  'mysql',	
  
	
  	
  	
  	
  'host'	
  	
  	
  	
  	
  	
  =>	
  'host',	
  
	
  	
  	
  	
  'database'	
  	
  =>	
  'database',	
  
	
  	
  	
  	
  //	
  ...	
  
]);	
  
$capsule-­‐>setAsGlobal();	
  
$capsule-­‐>bootEloquent();
$	
  composer	
  require	
  illuminate/database
嫌太⿇麻煩?
{	
  
	
  	
  	
  	
  "require":	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  "recca0120/laravel-­‐bridge":	
  "^1.0.0"	
  
	
  	
  	
  	
  }	
  
}
寫好	
  Pacakge	
  等你裝!
$	
  composer	
  require	
  recca0120/laravel-­‐bridge
//	
  bootstrap.php	
  
<?php	
  
use	
  Recca0120LaravelBridgeLaravel;	
  
require	
  __DIR__.'/vendor/autoload.php';	
  
$connections	
  =	
  [	
  
	
  	
  	
  //	
  ...	
  
];	
  
Laravel::instance()	
  
	
  	
  	
  	
  -­‐>setupView(...,	
  ...)	
  
	
  	
  	
  	
  -­‐>setupDatabase($connections)	
  
	
  	
  	
  	
  -­‐>setupPagination()	
  
	
  	
  	
  	
  -­‐>setupTracy([	
  
	
  	
  	
  	
  	
  	
  	
  	
  'showBar'	
  =>	
  true	
  
	
  	
  	
  	
  ]);
★ 跟 Codeigniter 整合範例:
https://github.com/recca0120/laraigniter
導⼊入⾃自動化
只要重覆兩次以上的事情,
都有做⾃自動化的價值。
- 得寬 DevOps
http://blog.chengweichen.com/	
  
優化時機
• 建⽴立環境時
- ⽤用 Bash、⽤用 Automation Tool 來建⽴立環境
• 建⽴立專案時
- 使⽤用 composer	
  create-­‐project 簡化專案啟動步驟
• 部署專案時
- 使⽤用 task runner 協助部署動作
⾃自動化安裝環境
⾄至少可以先從 Bash 開始!
https://goo.gl/Ntf9lrhttps://github.com/laravel/settler
使⽤用⾃自⼰己的 skeleton
$	
  composer	
  create-­‐project	
  {my/skeleton}
Composer Script Events
"scripts":	
  {	
  
	
  	
  	
  	
  "post-­‐root-­‐package-­‐install":	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  "php	
  -­‐r	
  "copy('.env.example',	
  '.env');""	
  
	
  	
  	
  	
  ],	
  
	
  	
  	
  	
  "post-­‐create-­‐project-­‐cmd":	
  [	
  
	
  	
  	
  	
  	
  	
  	
  "php	
  artisan	
  key:generate"	
  
	
  	
  	
  	
  ],	
  
	
  	
  	
  	
  "post-­‐install-­‐cmd":	
  [	
  
	
  	
  	
  	
  	
  	
  	
  "IlluminateFoundationComposerScripts::postInstall",	
  
	
  	
  	
  	
  	
  	
  	
  "php	
  artisan	
  optimize"	
  
	
  	
  	
  	
  ]	
  
},
$	
  composer	
  run-­‐script	
  {event}
⾃自動化部署
Local
$	
  envoy	
  run	
  deploy
Server	
  3Server	
  1 Server	
  2
Cloud	
  Servers //	
  Envoy.blade.php	
  
@servers(['web'	
  =>	
  '192.168.1.1'])	
  
@task('deploy',	
  ['on'	
  =>	
  'web'])	
  
	
  	
  	
  	
  cd	
  site	
  
	
  	
  	
  	
  git	
  pull	
  origin	
  {{	
  $branch	
  }}	
  
	
  	
  	
  	
  php	
  artisan	
  migrate	
  
@endtask
讓你的 PHP 專案潮起來!
優化
環境建置流程
升級
開發⼯工具
導⼊入
Composer
導⼊入
Migration
導⼊入
適⽤用框架
導⼊入
⾃自動化
透過可獨⽴立各別導⼊入的施⼒力點,⼀一步⼀一步現代化你的專案!
⼿手上有 Legacy 專案想升到 Laravel 嗎?
歡迎來找我們聊聊!
http://www.theqwan.com/contact
Q & A
感謝聆聽.歡迎交流

More Related Content

What's hot

Qemu device prototyping
Qemu device prototypingQemu device prototyping
Qemu device prototypingYan Vugenfirer
 
以 Laravel 經驗開發 Hyperf 應用
以 Laravel 經驗開發 Hyperf 應用以 Laravel 經驗開發 Hyperf 應用
以 Laravel 經驗開發 Hyperf 應用Shengyou Fan
 
Quick tour of PHP from inside
Quick tour of PHP from insideQuick tour of PHP from inside
Quick tour of PHP from insidejulien pauli
 
Meet cute-between-ebpf-and-tracing
Meet cute-between-ebpf-and-tracingMeet cute-between-ebpf-and-tracing
Meet cute-between-ebpf-and-tracingViller Hsiao
 
도커 없이 컨테이너 만들기 2편
도커 없이 컨테이너 만들기 2편도커 없이 컨테이너 만들기 2편
도커 없이 컨테이너 만들기 2편Sam Kim
 
Linux kernel tracing
Linux kernel tracingLinux kernel tracing
Linux kernel tracingViller Hsiao
 
Itamae-Serverspec入門
Itamae-Serverspec入門Itamae-Serverspec入門
Itamae-Serverspec入門辰徳 斎藤
 
Linux Native, HTTP Aware Network Security
Linux Native, HTTP Aware Network SecurityLinux Native, HTTP Aware Network Security
Linux Native, HTTP Aware Network SecurityThomas Graf
 
Crash Analysis with Reverse Taint
Crash Analysis with Reverse TaintCrash Analysis with Reverse Taint
Crash Analysis with Reverse Taintmarekzmyslowski
 
OpenStack DevStack Install - 2부 (Multi-nodes)
OpenStack DevStack Install - 2부 (Multi-nodes)OpenStack DevStack Install - 2부 (Multi-nodes)
OpenStack DevStack Install - 2부 (Multi-nodes)Ian Choi
 
第一次用 Vue.js 就愛上 [改]
第一次用 Vue.js 就愛上 [改]第一次用 Vue.js 就愛上 [改]
第一次用 Vue.js 就愛上 [改]Kuro Hsu
 
LLVM Backend の紹介
LLVM Backend の紹介LLVM Backend の紹介
LLVM Backend の紹介Akira Maruoka
 
Linux Performance Analysis and Tools
Linux Performance Analysis and ToolsLinux Performance Analysis and Tools
Linux Performance Analysis and ToolsBrendan Gregg
 
Introduction to PowerShell
Introduction to PowerShellIntroduction to PowerShell
Introduction to PowerShellSalaudeen Rajack
 
Linux Kernel MMC Storage driver Overview
Linux Kernel MMC Storage driver OverviewLinux Kernel MMC Storage driver Overview
Linux Kernel MMC Storage driver OverviewRajKumar Rampelli
 
Configuration management with puppet
Configuration management with puppetConfiguration management with puppet
Configuration management with puppetJakub Stransky
 
CSW2017 Qinghao tang+Xinlei ying vmware_escape_final
CSW2017 Qinghao tang+Xinlei ying vmware_escape_finalCSW2017 Qinghao tang+Xinlei ying vmware_escape_final
CSW2017 Qinghao tang+Xinlei ying vmware_escape_finalCanSecWest
 
Linux PCI device driver
Linux PCI device driverLinux PCI device driver
Linux PCI device driver艾鍗科技
 

What's hot (20)

Qemu device prototyping
Qemu device prototypingQemu device prototyping
Qemu device prototyping
 
以 Laravel 經驗開發 Hyperf 應用
以 Laravel 經驗開發 Hyperf 應用以 Laravel 經驗開發 Hyperf 應用
以 Laravel 經驗開發 Hyperf 應用
 
Quick tour of PHP from inside
Quick tour of PHP from insideQuick tour of PHP from inside
Quick tour of PHP from inside
 
Meet cute-between-ebpf-and-tracing
Meet cute-between-ebpf-and-tracingMeet cute-between-ebpf-and-tracing
Meet cute-between-ebpf-and-tracing
 
도커 없이 컨테이너 만들기 2편
도커 없이 컨테이너 만들기 2편도커 없이 컨테이너 만들기 2편
도커 없이 컨테이너 만들기 2편
 
Linux kernel tracing
Linux kernel tracingLinux kernel tracing
Linux kernel tracing
 
Itamae-Serverspec入門
Itamae-Serverspec入門Itamae-Serverspec入門
Itamae-Serverspec入門
 
Linux Native, HTTP Aware Network Security
Linux Native, HTTP Aware Network SecurityLinux Native, HTTP Aware Network Security
Linux Native, HTTP Aware Network Security
 
Crash Analysis with Reverse Taint
Crash Analysis with Reverse TaintCrash Analysis with Reverse Taint
Crash Analysis with Reverse Taint
 
OpenStack DevStack Install - 2부 (Multi-nodes)
OpenStack DevStack Install - 2부 (Multi-nodes)OpenStack DevStack Install - 2부 (Multi-nodes)
OpenStack DevStack Install - 2부 (Multi-nodes)
 
第一次用 Vue.js 就愛上 [改]
第一次用 Vue.js 就愛上 [改]第一次用 Vue.js 就愛上 [改]
第一次用 Vue.js 就愛上 [改]
 
Vagrant
VagrantVagrant
Vagrant
 
LLVM Backend の紹介
LLVM Backend の紹介LLVM Backend の紹介
LLVM Backend の紹介
 
Linux Performance Analysis and Tools
Linux Performance Analysis and ToolsLinux Performance Analysis and Tools
Linux Performance Analysis and Tools
 
Introduction to PowerShell
Introduction to PowerShellIntroduction to PowerShell
Introduction to PowerShell
 
Linux Kernel MMC Storage driver Overview
Linux Kernel MMC Storage driver OverviewLinux Kernel MMC Storage driver Overview
Linux Kernel MMC Storage driver Overview
 
NMap
NMapNMap
NMap
 
Configuration management with puppet
Configuration management with puppetConfiguration management with puppet
Configuration management with puppet
 
CSW2017 Qinghao tang+Xinlei ying vmware_escape_final
CSW2017 Qinghao tang+Xinlei ying vmware_escape_finalCSW2017 Qinghao tang+Xinlei ying vmware_escape_final
CSW2017 Qinghao tang+Xinlei ying vmware_escape_final
 
Linux PCI device driver
Linux PCI device driverLinux PCI device driver
Linux PCI device driver
 

Viewers also liked

Composer 從入門到實戰
Composer 從入門到實戰Composer 從入門到實戰
Composer 從入門到實戰Shengyou Fan
 
Visual Studio Code 快速上手指南
Visual Studio Code 快速上手指南Visual Studio Code 快速上手指南
Visual Studio Code 快速上手指南Shengyou Fan
 
使用 wagon + VS Code 輕鬆打造 Windows 平台 PHP/Laravel 開發環境
使用 wagon + VS Code 輕鬆打造 Windows 平台 PHP/Laravel 開發環境使用 wagon + VS Code 輕鬆打造 Windows 平台 PHP/Laravel 開發環境
使用 wagon + VS Code 輕鬆打造 Windows 平台 PHP/Laravel 開發環境Shengyou Fan
 
COSCUP 2016 Laravel 部署工作坊 - 生態圈介紹
COSCUP 2016 Laravel 部署工作坊 - 生態圈介紹COSCUP 2016 Laravel 部署工作坊 - 生態圈介紹
COSCUP 2016 Laravel 部署工作坊 - 生態圈介紹Shengyou Fan
 
開發環境建置
開發環境建置開發環境建置
開發環境建置Shengyou Fan
 
Composer 套件管理
Composer 套件管理Composer 套件管理
Composer 套件管理Shengyou Fan
 
凌波微步:wagon + VS Code 的輕功哲學
凌波微步:wagon + VS Code 的輕功哲學凌波微步:wagon + VS Code 的輕功哲學
凌波微步:wagon + VS Code 的輕功哲學Shengyou Fan
 
Route 路由控制
Route 路由控制Route 路由控制
Route 路由控制Shengyou Fan
 
Package 安裝與使用
Package 安裝與使用Package 安裝與使用
Package 安裝與使用Shengyou Fan
 
啟動 Laravel 與環境設定
啟動 Laravel 與環境設定啟動 Laravel 與環境設定
啟動 Laravel 與環境設定Shengyou Fan
 
COSCUP 2016 Laravel 部署工作坊 - 部署指南
COSCUP 2016 Laravel 部署工作坊 - 部署指南COSCUP 2016 Laravel 部署工作坊 - 部署指南
COSCUP 2016 Laravel 部署工作坊 - 部署指南Shengyou Fan
 
使用 Visual Studio Code 建構 JavaScript 應用程式
使用 Visual Studio Code 建構 JavaScript 應用程式使用 Visual Studio Code 建構 JavaScript 應用程式
使用 Visual Studio Code 建構 JavaScript 應用程式Will Huang
 
View 與 Blade 樣板引擎
View 與 Blade 樣板引擎View 與 Blade 樣板引擎
View 與 Blade 樣板引擎Shengyou Fan
 
Migrations 與 Schema 操作
Migrations 與 Schema 操作Migrations 與 Schema 操作
Migrations 與 Schema 操作Shengyou Fan
 
Model 設定與 Seeding
Model 設定與 SeedingModel 設定與 Seeding
Model 設定與 SeedingShengyou Fan
 
Laravel 台灣 南進台中 社群小聚 - 社群現況報馬仔 2015/10
Laravel 台灣 南進台中 社群小聚 - 社群現況報馬仔 2015/10Laravel 台灣 南進台中 社群小聚 - 社群現況報馬仔 2015/10
Laravel 台灣 南進台中 社群小聚 - 社群現況報馬仔 2015/10Shengyou Fan
 
Google api應用入門
Google api應用入門Google api應用入門
Google api應用入門Simon Su
 

Viewers also liked (20)

Composer 從入門到實戰
Composer 從入門到實戰Composer 從入門到實戰
Composer 從入門到實戰
 
Visual Studio Code 快速上手指南
Visual Studio Code 快速上手指南Visual Studio Code 快速上手指南
Visual Studio Code 快速上手指南
 
使用 wagon + VS Code 輕鬆打造 Windows 平台 PHP/Laravel 開發環境
使用 wagon + VS Code 輕鬆打造 Windows 平台 PHP/Laravel 開發環境使用 wagon + VS Code 輕鬆打造 Windows 平台 PHP/Laravel 開發環境
使用 wagon + VS Code 輕鬆打造 Windows 平台 PHP/Laravel 開發環境
 
COSCUP 2016 Laravel 部署工作坊 - 生態圈介紹
COSCUP 2016 Laravel 部署工作坊 - 生態圈介紹COSCUP 2016 Laravel 部署工作坊 - 生態圈介紹
COSCUP 2016 Laravel 部署工作坊 - 生態圈介紹
 
開發環境建置
開發環境建置開發環境建置
開發環境建置
 
Composer 套件管理
Composer 套件管理Composer 套件管理
Composer 套件管理
 
凌波微步:wagon + VS Code 的輕功哲學
凌波微步:wagon + VS Code 的輕功哲學凌波微步:wagon + VS Code 的輕功哲學
凌波微步:wagon + VS Code 的輕功哲學
 
工作坊總結
工作坊總結工作坊總結
工作坊總結
 
Route 路由控制
Route 路由控制Route 路由控制
Route 路由控制
 
工作坊簡介
工作坊簡介工作坊簡介
工作坊簡介
 
Package 安裝與使用
Package 安裝與使用Package 安裝與使用
Package 安裝與使用
 
啟動 Laravel 與環境設定
啟動 Laravel 與環境設定啟動 Laravel 與環境設定
啟動 Laravel 與環境設定
 
COSCUP 2016 Laravel 部署工作坊 - 部署指南
COSCUP 2016 Laravel 部署工作坊 - 部署指南COSCUP 2016 Laravel 部署工作坊 - 部署指南
COSCUP 2016 Laravel 部署工作坊 - 部署指南
 
使用 Controller
使用 Controller使用 Controller
使用 Controller
 
使用 Visual Studio Code 建構 JavaScript 應用程式
使用 Visual Studio Code 建構 JavaScript 應用程式使用 Visual Studio Code 建構 JavaScript 應用程式
使用 Visual Studio Code 建構 JavaScript 應用程式
 
View 與 Blade 樣板引擎
View 與 Blade 樣板引擎View 與 Blade 樣板引擎
View 與 Blade 樣板引擎
 
Migrations 與 Schema 操作
Migrations 與 Schema 操作Migrations 與 Schema 操作
Migrations 與 Schema 操作
 
Model 設定與 Seeding
Model 設定與 SeedingModel 設定與 Seeding
Model 設定與 Seeding
 
Laravel 台灣 南進台中 社群小聚 - 社群現況報馬仔 2015/10
Laravel 台灣 南進台中 社群小聚 - 社群現況報馬仔 2015/10Laravel 台灣 南進台中 社群小聚 - 社群現況報馬仔 2015/10
Laravel 台灣 南進台中 社群小聚 - 社群現況報馬仔 2015/10
 
Google api應用入門
Google api應用入門Google api應用入門
Google api應用入門
 

Similar to [Modern Web 2016] 讓你的 PHP 開發流程再次潮起來

Ruby on Rails 開發環境建置 for Ubuntu
Ruby on Rails 開發環境建置 for UbuntuRuby on Rails 開發環境建置 for Ubuntu
Ruby on Rails 開發環境建置 for UbuntuMarsZ Chen
 
Ruby on Rails 開發環境建置 for Mac
Ruby on Rails 開發環境建置 for MacRuby on Rails 開發環境建置 for Mac
Ruby on Rails 開發環境建置 for MacMarsZ Chen
 
Openshift by mtchang
Openshift by mtchangOpenshift by mtchang
Openshift by mtchangChang Mt
 
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩Wen-Tien Chang
 
X64服务器 lamp服务器部署标准 new
X64服务器 lamp服务器部署标准 newX64服务器 lamp服务器部署标准 new
X64服务器 lamp服务器部署标准 newYiwei Ma
 
[Modern Web Conf 2015] 給 PHP 開發者的 Composer 錦囊
[Modern Web Conf 2015] 給 PHP 開發者的 Composer 錦囊[Modern Web Conf 2015] 給 PHP 開發者的 Composer 錦囊
[Modern Web Conf 2015] 給 PHP 開發者的 Composer 錦囊Shengyou Fan
 
康盛创想项目部Linux 服务器部署标准(最新版)
康盛创想项目部Linux 服务器部署标准(最新版)康盛创想项目部Linux 服务器部署标准(最新版)
康盛创想项目部Linux 服务器部署标准(最新版)Yiwei Ma
 
基于 FRIDA 的全平台逆向分析
基于 FRIDA 的全平台逆向分析基于 FRIDA 的全平台逆向分析
基于 FRIDA 的全平台逆向分析CC
 
GNU Autoconf / Automake #1
GNU Autoconf / Automake #1GNU Autoconf / Automake #1
GNU Autoconf / Automake #1imacat .
 
利用Cent Os快速构建自己的发行版
利用Cent Os快速构建自己的发行版利用Cent Os快速构建自己的发行版
利用Cent Os快速构建自己的发行版xingsu1021
 
Php可调试团队开发环境配置
Php可调试团队开发环境配置Php可调试团队开发环境配置
Php可调试团队开发环境配置xinqi yang
 
Php可调试团队开发环境配置
Php可调试团队开发环境配置Php可调试团队开发环境配置
Php可调试团队开发环境配置wangkangluo1
 
02.python.开发最佳实践
02.python.开发最佳实践02.python.开发最佳实践
02.python.开发最佳实践Na Lee
 
Sery lvs+keepalived
Sery lvs+keepalivedSery lvs+keepalived
Sery lvs+keepalivedcolderboy17
 
Centos下安装apache + subversion
Centos下安装apache + subversionCentos下安装apache + subversion
Centos下安装apache + subversionYiwei Ma
 
現代 IT 人一定要知道的 Ansible 自動化組態技巧 Ⅱ - Roles & Windows
現代 IT 人一定要知道的 Ansible 自動化組態技巧 Ⅱ - Roles & Windows現代 IT 人一定要知道的 Ansible 自動化組態技巧 Ⅱ - Roles & Windows
現代 IT 人一定要知道的 Ansible 自動化組態技巧 Ⅱ - Roles & WindowsChu-Siang Lai
 
Puppet安装总结
Puppet安装总结Puppet安装总结
Puppet安装总结Yiwei Ma
 
2012 java two-desktop-appliction-using-j-ruby-with-swt
2012 java two-desktop-appliction-using-j-ruby-with-swt2012 java two-desktop-appliction-using-j-ruby-with-swt
2012 java two-desktop-appliction-using-j-ruby-with-swttka
 

Similar to [Modern Web 2016] 讓你的 PHP 開發流程再次潮起來 (20)

Ruby on Rails 開發環境建置 for Ubuntu
Ruby on Rails 開發環境建置 for UbuntuRuby on Rails 開發環境建置 for Ubuntu
Ruby on Rails 開發環境建置 for Ubuntu
 
Ruby on Rails 開發環境建置 for Mac
Ruby on Rails 開發環境建置 for MacRuby on Rails 開發環境建置 for Mac
Ruby on Rails 開發環境建置 for Mac
 
Openshift by mtchang
Openshift by mtchangOpenshift by mtchang
Openshift by mtchang
 
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
 
X64服务器 lamp服务器部署标准 new
X64服务器 lamp服务器部署标准 newX64服务器 lamp服务器部署标准 new
X64服务器 lamp服务器部署标准 new
 
[Modern Web Conf 2015] 給 PHP 開發者的 Composer 錦囊
[Modern Web Conf 2015] 給 PHP 開發者的 Composer 錦囊[Modern Web Conf 2015] 給 PHP 開發者的 Composer 錦囊
[Modern Web Conf 2015] 給 PHP 開發者的 Composer 錦囊
 
康盛创想项目部Linux 服务器部署标准(最新版)
康盛创想项目部Linux 服务器部署标准(最新版)康盛创想项目部Linux 服务器部署标准(最新版)
康盛创想项目部Linux 服务器部署标准(最新版)
 
Linuxguide4f2e
Linuxguide4f2eLinuxguide4f2e
Linuxguide4f2e
 
LinuxGuide4F2E
LinuxGuide4F2ELinuxGuide4F2E
LinuxGuide4F2E
 
基于 FRIDA 的全平台逆向分析
基于 FRIDA 的全平台逆向分析基于 FRIDA 的全平台逆向分析
基于 FRIDA 的全平台逆向分析
 
GNU Autoconf / Automake #1
GNU Autoconf / Automake #1GNU Autoconf / Automake #1
GNU Autoconf / Automake #1
 
利用Cent Os快速构建自己的发行版
利用Cent Os快速构建自己的发行版利用Cent Os快速构建自己的发行版
利用Cent Os快速构建自己的发行版
 
Php可调试团队开发环境配置
Php可调试团队开发环境配置Php可调试团队开发环境配置
Php可调试团队开发环境配置
 
Php可调试团队开发环境配置
Php可调试团队开发环境配置Php可调试团队开发环境配置
Php可调试团队开发环境配置
 
02.python.开发最佳实践
02.python.开发最佳实践02.python.开发最佳实践
02.python.开发最佳实践
 
Sery lvs+keepalived
Sery lvs+keepalivedSery lvs+keepalived
Sery lvs+keepalived
 
Centos下安装apache + subversion
Centos下安装apache + subversionCentos下安装apache + subversion
Centos下安装apache + subversion
 
現代 IT 人一定要知道的 Ansible 自動化組態技巧 Ⅱ - Roles & Windows
現代 IT 人一定要知道的 Ansible 自動化組態技巧 Ⅱ - Roles & Windows現代 IT 人一定要知道的 Ansible 自動化組態技巧 Ⅱ - Roles & Windows
現代 IT 人一定要知道的 Ansible 自動化組態技巧 Ⅱ - Roles & Windows
 
Puppet安装总结
Puppet安装总结Puppet安装总结
Puppet安装总结
 
2012 java two-desktop-appliction-using-j-ruby-with-swt
2012 java two-desktop-appliction-using-j-ruby-with-swt2012 java two-desktop-appliction-using-j-ruby-with-swt
2012 java two-desktop-appliction-using-j-ruby-with-swt
 

More from Shengyou Fan

[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式Shengyou Fan
 
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...Shengyou Fan
 
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀Shengyou Fan
 
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能Shengyou Fan
 
How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023Shengyou Fan
 
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀Shengyou Fan
 
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台Shengyou Fan
 
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇Shengyou Fan
 
Using the Exposed SQL Framework to Manage Your Database
Using the Exposed SQL Framework to Manage Your DatabaseUsing the Exposed SQL Framework to Manage Your Database
Using the Exposed SQL Framework to Manage Your DatabaseShengyou Fan
 
[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園Shengyou Fan
 
初探 Kotlin Multiplatform
初探 Kotlin Multiplatform初探 Kotlin Multiplatform
初探 Kotlin MultiplatformShengyou Fan
 
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率Shengyou Fan
 
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用Shengyou Fan
 
Composer 經典食譜
Composer 經典食譜Composer 經典食譜
Composer 經典食譜Shengyou Fan
 
老派浪漫:用 Kotlin 寫 Command Line 工具
老派浪漫:用 Kotlin 寫 Command Line 工具老派浪漫:用 Kotlin 寫 Command Line 工具
老派浪漫:用 Kotlin 寫 Command Line 工具Shengyou Fan
 
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS AggregatorShengyou Fan
 
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON APIShengyou Fan
 
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin ServerlessShengyou Fan
 
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置Shengyou Fan
 
用 Kotlin 打造讀書會小幫手
用 Kotlin 打造讀書會小幫手用 Kotlin 打造讀書會小幫手
用 Kotlin 打造讀書會小幫手Shengyou Fan
 

More from Shengyou Fan (20)

[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
 
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
 
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
 
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
 
How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023
 
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
 
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
 
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
 
Using the Exposed SQL Framework to Manage Your Database
Using the Exposed SQL Framework to Manage Your DatabaseUsing the Exposed SQL Framework to Manage Your Database
Using the Exposed SQL Framework to Manage Your Database
 
[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園
 
初探 Kotlin Multiplatform
初探 Kotlin Multiplatform初探 Kotlin Multiplatform
初探 Kotlin Multiplatform
 
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
 
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
 
Composer 經典食譜
Composer 經典食譜Composer 經典食譜
Composer 經典食譜
 
老派浪漫:用 Kotlin 寫 Command Line 工具
老派浪漫:用 Kotlin 寫 Command Line 工具老派浪漫:用 Kotlin 寫 Command Line 工具
老派浪漫:用 Kotlin 寫 Command Line 工具
 
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
 
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
 
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
 
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
 
用 Kotlin 打造讀書會小幫手
用 Kotlin 打造讀書會小幫手用 Kotlin 打造讀書會小幫手
用 Kotlin 打造讀書會小幫手
 

[Modern Web 2016] 讓你的 PHP 開發流程再次潮起來