Membina & Menjalankan Projek Zend Framework (Laminas) dengan ServBay
Pengenalan
Zend Framework (kini sebahagian daripada Laminas Project) ialah rangka kerja PHP sumber terbuka yang mantap, menyediakan rangkaian komponen berorientasikan objek berkualiti tinggi untuk membina aplikasi dan servis Web moden. Dengan reka bentuk modular, fleksibel, serta kecekapan tinggi, ia sesuai untuk membangun laman web ringkas hingga aplikasi perusahaan yang kompleks.
ServBay ialah persekitaran pembangunan web tempatan untuk macOS dan Windows, menggabungkan PHP, pelbagai pelayan web (Caddy, Nginx), pangkalan data (MySQL, PostgreSQL, MongoDB), servis cache (Redis, Memcached) dan pelbagai alat pemrograman lain. ServBay memudahkan anda mengurus dan mengkonfigurasi semua perisian ini agar projek PHP anda dapat dijalankan secara lokal dengan sangat mudah.
Dokumen ini membimbing anda untuk membina dan menjalankan projek Zend Framework (Laminas) di persekitaran ServBay, termasuk contoh integrasi pangkalan data dan servis cache yang disediakan oleh ServBay.
Pra-Syarat
Sebelum bermula, pastikan anda sudah lakukan berikut:
- Pasang ServBay: ServBay sudah terpasang dan berfungsi di macOS atau Windows. Jika belum, lawati laman rasmi ServBay untuk arahan pemasangan.
- Pakej ServBay: Pastikan pakej-pakej berikut telah dipasang dan dijalankan:
- Sekurang-kurangnya satu versi PHP (disarankan PHP 8.x ke atas; versi terbaru Zend Framework memerlukan PHP terkini).
- Pelayan web (Caddy atau Nginx).
- Composer (biasanya tersedia secara lalai di ServBay).
- Servis pangkalan data pilihan anda (MySQL, PostgreSQL) dan servis cache (Memcached, Redis). Anda boleh mengaktifkan semuanya dalam panel kawalan ServBay.
Mencipta Projek Zend Framework
ServBay mengesyorkan semua projek laman web disimpan di direktori berikut agar pengurusan dan konfigurasi automatik lebih mudah:
- macOS:
/Applications/ServBay/www
- Windows:
C:\ServBay\www
Navigasi ke Direktori Root Laman
Buka Terminal dan pergi ke direktori root yang disyorkan:
macOS:
bashcd /Applications/ServBay/www
1Windows:
cmdcd C:\ServBay\www
1Cipta Projek dengan Composer
Composer sudah tersedia dalam ServBay. Gunakan perintah
create-project
untuk mencipta aplikasi skeleton Zend Framework (Laminas) yang baru di dalam subdirektoriservbay-zend-app
:bashcomposer create-project laminas/laminas-skeleton-application servbay-zend-app
1Ini akan memuat turun rangka kerja skeleton ke direktori
servbay-zend-app
dan memasang semua kebergantungan yang diperlukan.Masuk ke Direktori Projek
Navigasi ke dalam direktori projek anda:
bashcd servbay-zend-app
1
Konfigurasi Pelayan Web
Agar laman Zend Framework anda boleh diakses melalui pelayar, anda perlu konfigurasikan website dalam ServBay.
- Buka Panel Kawalan ServBay: Jalankan aplikasi ServBay.
- Pergi ke Tetapan Website: Klik tab Website.
- Tambah Website Baru: Klik butang
+
di sudut bawah kiri untuk menambah konfigurasi website baru. - Isi Maklumat Website:
- Nama: Nama mudah dikenali, contoh
My Zend Dev Site
. - Domain: Masukkan domain yang akan diakses. Elakkan konflik dengan domain nyata, misalkan guna akhiran
.local
atau.test
sepertiservbay-zend-test.local
. ServBay akan auto-konfig DNS tempatan. - Jenis Website: Pilih
PHP
. - Versi PHP: Pilih versi PHP (misal
8.3
) yang ingin digunakan. Pastikan versi ini aktif di ServBay. - Root Dokumen: Direktori servis laman anda. Folder
index.php
Zend Framework berada di dalam folderpublic
projek anda:.../servbay-zend-app/public
.
- Nama: Nama mudah dikenali, contoh
- Simpan & Restart: Klik Simpan. Ikuti arahan untuk memuat semula konfigurasi pelayan agar website baru anda diaktifkan.
Rujuk tutorial Tambah Laman Pertama ServBay untuk langkah terperinci.
Contoh Asas "Hello ServBay!"
Mari ubah kod projek agar ketika melawat URL root (/
), ia memaparkan "Hello ServBay!".
Konfigurasi Router & Controller (module.config.php)
Edit
module/Application/config/module.config.php
dan pastikan konfigurasi asas router dan controller berikut ada:php<?php declare(strict_types=1); namespace Application; use Laminas\Router\Http\Literal; use Laminas\Router\Http\Segment; use Laminas\ServiceManager\Factory\InvokableFactory; return [ 'router' => [ 'routes' => [ 'home' => [ 'type' => Literal::class, 'options' => [ 'route' => '/', 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'index', ], ], ], // ... Konfigurasi router lain ], ], 'controllers' => [ 'factories' => [ Controller\IndexController::class => InvokableFactory::class, ], ], 'view_manager' => [ 'display_not_found_reason' => true, 'display_exceptions' => true, 'doctype' => 'HTML5', 'not_found_template' => 'error/404', 'exception_template' => 'error/index', 'template_map' => [ 'layout/layout' => __DIR__ . '/../view/layout/layout.phtml', 'application/index/index' => __DIR__ . '/../view/application/index/index.phtml', 'error/404' => __DIR__ . '/../view/error/404.phtml', 'error/index' => __DIR__ . '/../view/error/index.phtml', ], 'template_path_stack' => [ __DIR__ . '/../view', ], ], // ... Konfigurasi lain ];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49Nota: Kod di atas ialah sebahagian dari
module.config.php
; gabungkan ke dalam array konfigurasi yang sedia ada dan pastikanhome
dan factory untukIndexController
telah ada.Cipta atau Ubah Controller (IndexController.php)
Edit atau cipta
module/Application/src/Controller/IndexController.php
. PastikanindexAction
mengembalikan ViewModel yang mengandungi mesej:php<?php declare(strict_types=1); namespace Application\Controller; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; class IndexController extends AbstractActionController { /** * Default action untuk paparan halaman selamat datang. */ public function indexAction() { // Return ViewModel dan hantar 'message' ke view return new ViewModel([ 'message' => 'Hello ServBay!', ]); } // ... action lain }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24Cipta atau Ubah Fail View (index.phtml)
Edit atau cipta
module/Application/view/application/index/index.phtml
:php<h1><?php echo $this->message; ?></h1>
1Gunakan pembantu view
$this->message
untuk mengakses data yang diterima dari controller.
Mengakses Laman Anda
Buka pelayar dan lawat domain yang telah anda konfigurasikan, contoh https://servbay-zend-test.local
.
Jika konfigurasi berjaya, halaman harus memaparkan Hello ServBay!
. Bermakna projek Zend Framework anda telah berjalan di ServBay.
Contoh Integrasi Pangkalan Data & Cache
ServBay menyediakan pelbagai servis pangkalan data dan cache. Berikut ialah contoh bagaimana menghubungkan Memcached, Redis, MySQL, dan PostgreSQL dalam projek Zend Framework.
Penting: Setiap demo adalah bebas. Dalam projek sebenar, pilih satu pangkalan data dan satu atau lebih servis cache mengikut keperluan, serta gunakan kaedah pengurusan sambungan seperti dependency injection. Untuk cuba kod berikut, pastikan servis yang berkaitan (MySQL, PostgreSQL, Memcached, Redis) telah diaktifkan melalui ServBay.
Contoh Interaksi DB – Cipta Table
Contoh menggunakan komponen Laminas DB untuk berinteraksi dengan database, termasuk mencipta table ringkas.
Pasang Komponen Laminas DB
Di root projek, pasang dengan Composer:
bashcomposer require laminas/laminas-db
1Cipta Database Secara Manual
Sebelum jalankan kod contoh, cipta database bernama
servbay_zend_app
melalui alat pengurusan (phpMyAdmin, pgAdmin, dsb.) dalam ServBay. Username lalai untuk MySQL/MariaDB dan PostgreSQL ialahroot
, password ialahpassword
.Tulis & Jalankan Skrip Buat Table
Cipta fail PHP (contoh:
create_users_table.php
) dan tambahkan kod berikut untuk cipta tableusers
:php<?php // create_users_table.php use Laminas\Db\Adapter\Adapter; use Laminas\Db\Sql\Sql; // Anggap gunakan MySQL atau MariaDB $adapter = new Adapter([ 'driver' => 'Pdo_Mysql', // atau 'Pdo_Pgsql' 'database' => 'servbay_zend_app', 'username' => 'root', 'password' => 'password', // Password lalai ServBay 'hostname' => '127.0.0.1', // 'port' => 3306, // MySQL // 'port' => 5432, // PostgreSQL ]); $sql = new Sql($adapter); // Definisi SQL penciptaan table users $create = $sql->createTable('users') ->addColumn(new \Laminas\Db\Sql\Ddl\Column\Integer('id', false, null, ['AUTO_INCREMENT' => true])) ->addColumn(new \Laminas\Db\Sql\Ddl\Column\Varchar('name', 255)) ->addColumn(new \Laminas\Db\Sql\Ddl\Column\Varchar('email', 255, ['UNIQUE' => true])) ->addConstraint(new \Laminas\Db\Sql\Ddl\Constraint\PrimaryKey('id')); echo "Melaksanakan SQL:\n"; echo $sql->buildSqlString($create, $adapter->getPlatform()) . "\n"; try { // Laksanakan SQL $adapter->query( $sql->buildSqlString($create, $adapter->getPlatform()), Adapter::QUERY_MODE_EXECUTE ); echo "Table 'users' berjaya dicipta.\n"; } catch (\Exception $e) { echo "Ralat mencipta table: " . $e->getMessage() . "\n"; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38Nota: Ini contoh manual. Biasanya pengurusan skema pangkalan data dilakukan dengan alat migrasi.
Jalankan skrip dengan PHP CLI:
bashphp create_users_table.php
1
Contoh Integrasi MySQL
Demo hubung & kueri ke MySQL dalam controller Zend Framework.
Konfigurasi Sambungan Database
Edit
config/autoload/global.php
untuk tetapan MySQL:php<?php // config/autoload/global.php return [ 'db' => [ 'driver' => 'Pdo_Mysql', 'database' => 'servbay_zend_app', 'username' => 'root', 'password' => 'password', 'hostname' => '127.0.0.1', 'port' => 3306, 'charset' => 'utf8mb4', ], // ... Konfigurasi lain ];
1
2
3
4
5
6
7
8
9
10
11
12
13
14Konfigurasi Controller Factory (module.config.php)
Untuk injection
Laminas\Db\Adapter\Adapter
ke controller, kemas kini konfigurasi controller ke factory berikut:php<?php // module/Application/config/module.config.php namespace Application; use Laminas\ServiceManager\Factory\InvokableFactory; use Laminas\Db\Adapter\AdapterInterface; return [ // ... 'controllers' => [ 'factories' => [ Controller\IndexController::class => function($container) { $adapter = $container->get(AdapterInterface::class); return new Controller\IndexController($adapter); }, ], ], 'service_manager' => [ 'aliases' => [ AdapterInterface::class => 'Laminas\Db\Adapter\Adapter', ], 'factories' => [ 'Laminas\Db\Adapter\Adapter' => \Laminas\Db\Adapter\AdapterServiceFactory::class, ], ], // ... ];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27Pastikan konfigurasi factory dan service manager telah betul.
Konfigurasi Router (module.config.php)
Tambahkan routing baru:
php<?php // module/Application/config/module.config.php namespace Application; use Laminas\Router\Http\Literal; return [ 'router' => [ 'routes' => [ // ... routing lain 'mysql-add' => [ 'type' => Literal::class, 'options' => [ 'route' => '/mysql-add', 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'mysqlAdd', ], ], ], 'mysql' => [ 'type' => Literal::class, 'options' => [ 'route' => '/mysql', 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'mysql', ], ], ], ], ], // ... ];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34Tambah Kaedah Controller (IndexController.php)
Tambahkan contructor,
mysqlAddAction
danmysqlAction
:php<?php declare(strict_types=1); namespace Application\Controller; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; use Laminas\Db\Adapter\AdapterInterface; use Laminas\Db\Sql\Sql; class IndexController extends AbstractActionController { private $adapter; public function __construct(AdapterInterface $adapter) { $this->adapter = $adapter; } public function indexAction() { return new ViewModel([ 'message' => 'Hello ServBay!', ]); } public function mysqlAddAction() { $sql = new Sql($this->adapter); $insert = $sql->insert('users') ->values([ 'name' => 'ServBay Demo User', 'email' => 'demo-mysql@servbay.test', ]); $statement = $sql->prepareStatementForSqlObject($insert); $result = $statement->execute(); $message = $result->getAffectedRows() > 0 ? 'Pengguna MySQL berjaya ditambah.' : 'Gagal menambah pengguna MySQL.'; return new ViewModel([ 'message' => $message, ]); } public function mysqlAction() { $sql = new Sql($this->adapter); $select = $sql->select('users'); $statement = $sql->prepareStatementForSqlObject($select); $result = $statement->execute(); $users = []; foreach ($result as $row) { $users[] = $row; } return new ViewModel([ 'users' => json_encode($users, JSON_PRETTY_PRINT), ]); } // ... action lain }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66Cipta Fail View
module/Application/view/application/index/mysql-add.phtml
:php<h1><?php echo $this->message; ?></h1>
1module/Application/view/application/index/mysql.phtml
:php<h1>Pengguna MySQL</h1> <pre><?php echo $this->users; ?></pre>
1
2Uji MySQL
Pastikan MySQL ServBay aktif. Lawat
https://servbay-zend-test.local/mysql-add
untuk tambah user, danhttps://servbay-zend-test.local/mysql
untuk paparan data.
Contoh Integrasi PostgreSQL
Langkahnya hampir sama seperti MySQL tetapi tukar sambungan kepada PostgreSQL.
Konfigurasi Sambungan Database
Edit
config/autoload/global.php
kepada tetapan PostgreSQL:php<?php return [ 'db' => [ 'driver' => 'Pdo_Pgsql', 'database' => 'servbay_zend_app', 'username' => 'root', 'password' => 'password', 'hostname' => '127.0.0.1', 'port' => 5432, ], // ... ];
1
2
3
4
5
6
7
8
9
10
11
12Konfigurasi Controller Factory & Service Manager
Ikuti contoh konfigurasi factory dan service manager di bahagian MySQL.
Konfigurasi Router
Tambahkan router
/pgsql-add
dan/pgsql
seperti berikut:php<?php // module/Application/config/module.config.php namespace Application; use Laminas\Router\Http\Literal; return [ 'router' => [ 'routes' => [ // ... routing lain 'pgsql-add' => [ 'type' => Literal::class, 'options' => [ 'route' => '/pgsql-add', 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'pgsqlAdd', ], ], ], 'pgsql' => [ 'type' => Literal::class, 'options' => [ 'route' => '/pgsql', 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'pgsql', ], ], ], ], ], // ... ];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34Tambah Kaedah Controller (IndexController.php)
php<?php declare(strict_types=1); namespace Application\Controller; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; use Laminas\Db\Adapter\AdapterInterface; use Laminas\Db\Sql\Sql; class IndexController extends AbstractActionController { private $adapter; public function __construct(AdapterInterface $adapter) { $this->adapter = $adapter; } // ... action sebelum ini public function pgsqlAddAction() { $sql = new Sql($this->adapter); $insert = $sql->insert('users') ->values([ 'name' => 'ServBay Demo User', 'email' => 'demo-pgsql@servbay.test', ]); $statement = $sql->prepareStatementForSqlObject($insert); $result = $statement->execute(); $message = $result->getAffectedRows() > 0 ? 'Pengguna PostgreSQL berjaya ditambah.' : 'Gagal menambah pengguna PostgreSQL.'; return new ViewModel([ 'message' => $message, ]); } public function pgsqlAction() { $sql = new Sql($this->adapter); $select = $sql->select('users'); $statement = $sql->prepareStatementForSqlObject($select); $result = $statement->execute(); $users = []; foreach ($result as $row) { $users[] = $row; } return new ViewModel([ 'users' => json_encode($users, JSON_PRETTY_PRINT), ]); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59Cipta Fail View
module/Application/view/application/index/pgsql-add.phtml
:php<h1><?php echo $this->message; ?></h1>
1module/Application/view/application/index/pgsql.phtml
:php<h1>Pengguna PostgreSQL</h1> <pre><?php echo $this->users; ?></pre>
1
2Uji PostgreSQL
Pastikan PostgreSQL ServBay aktif. Lawat
/pgsql-add
untuk tambah user, dan/pgsql
untuk paparan pengguna.
Contoh Integrasi Memcached
Demo penggunaan cache Memcached dalam controller Zend Framework.
Pasang Adapter Memcached
Tambahkan pada
composer.json
:json{ "require": { "laminas/laminas-skeleton-application": "^1.0", "laminas/laminas-cache-storage-adapter-memcached": "^2.0" } }
1
2
3
4
5
6Jalankan:
bashcomposer update
1PHP extension
memcached
sudah tersedia di ServBay.Konfigurasi Router
Tambahkan route
/memcached
:php'memcached' => [ 'type' => Literal::class, 'options' => [ 'route' => '/memcached', 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'memcached', ], ], ],
1
2
3
4
5
6
7
8
9
10Tambah Kaedah Controller (IndexController.php)
phpuse Laminas\Cache\StorageFactory; use Laminas\Cache\Storage\StorageInterface; public function memcachedAction() { // Buat instance cache Memcached $cache = StorageFactory::factory([ 'adapter' => [ 'name' => 'memcached', 'options' => [ 'servers' => [ ['127.0.0.1', 11211], ], 'ttl' => 300, ], ], 'plugins' => [ 'serializer', 'exception_handler' => ['throw_exceptions' => false], ], ]); $cacheKey = 'my_memcached_data'; $cachedData = $cache->getItem($cacheKey, $success); if (!$success) { $cachedData = 'Hello Memcached! (Data dari sumber, cache pada ' . date('Y-m-d H:i:s') . ')'; $cache->setItem($cacheKey, $cachedData); $cachedData .= ' - CACHE MISS'; } else { $cachedData .= ' - CACHE HIT'; } return new ViewModel([ 'message' => $cachedData, ]); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37Cipta Fail View
module/Application/view/application/index/memcached.phtml
:php<h1>Contoh Memcached</h1> <p><?php echo $this->message; ?></p>
1
2Uji Memcached
Pastikan servis Memcached aktif di ServBay. Lawat
/memcached
untuk melihat respons cache.
Contoh Integrasi Redis
Memaparkan cara menggunakan Redis untuk cache/storage dalam controller Zend Framework.
Pasang Adapter Redis
Tambah pada
composer.json
:json{ "require": { "laminas/laminas-skeleton-application": "^1.0", "laminas/laminas-cache-storage-adapter-redis": "^2.0", "ext-redis": "*" } }
1
2
3
4
5
6
7Jalankan:
bashcomposer update
1Extension
redis
PHP sudah dipasang dalam ServBay.Konfigurasi Router
Tambahkan route
/redis
dalammodule.config.php
:php'redis' => [ 'type' => Literal::class, 'options' => [ 'route' => '/redis', 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'redis', ], ], ],
1
2
3
4
5
6
7
8
9
10Tambah Kaedah Controller (IndexController.php)
phpuse Laminas\Cache\StorageFactory; use Laminas\Cache\Storage\StorageInterface; public function redisAction() { // Buat instance cache Redis $cache = StorageFactory::factory([ 'adapter' => [ 'name' => 'redis', 'options' => [ 'server' => [ 'host' => '127.0.0.1', 'port' => 6379, ], 'ttl' => 300, ], ], 'plugins' => [ 'serializer', 'exception_handler' => ['throw_exceptions' => false], ], ]); $cacheKey = 'my_redis_data'; $cachedData = $cache->getItem($cacheKey, $success); if (!$success) { $cachedData = 'Hello Redis! (Data dari sumber, cache pada ' . date('Y-m-d H:i:s') . ')'; $cache->setItem($cacheKey, $cachedData); $cachedData .= ' - CACHE MISS'; } else { $cachedData .= ' - CACHE HIT'; } return new ViewModel([ 'message' => $cachedData, ]); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38Cipta Fail View
module/Application/view/application/index/redis.phtml
:php<h1>Contoh Redis</h1> <p><?php echo $this->message; ?></p>
1
2Uji Redis
Pastikan servis Redis aktif di ServBay. Lawat
/redis
untuk menguji cache Redis.
Kesimpulan
Anda kini telah berjaya membina, mengkonfigurasi, dan menjalankan projek Zend Framework (Laminas) dalam persekitaran tempatan ServBay. Anda telah belajar mengkonfigurasi pelayan web agar laman menunjuk ke direktori public
, serta menghubungkan projek dengan pangkalan data MySQL, PostgreSQL, dan servis cache Memcached serta Redis.
ServBay memudahkan pengurusan dan pembangunan persekitaran tempatan, membolehkan anda fokus kepada pembangunan kod dan projek anda. Dengan pelbagai pakej disediakan dan konfigurasi yang fleksibel, anda boleh mensimulasikan persekitaran produksi secara lokal dengan lebih efisien.