• Tidak ada hasil yang ditemukan

Front Controller

Dalam dokumen Buku Belajar Santai OOP PHP (Halaman 187-199)

63 throw new \InvalidArgumentException(sprintf\

64 ('%s is not callable.', $controller));

65 }

66 $this->router->add($path, new Route(

67 $path,

68 array('_controller' => $controller)

69 ));

70 }

71 }

Sampai disini, sebenarnyaframework kita sudah jadi. Serius,core frameworksebenarnya memang sesimpel itu. Yang membuatframe- workterkesan kompleks adalah karena adanya proses validasi dan lain-lain padacoreataukerneldari framework tersebut.

Untukframeworkyang kita buat, proses-proses tersebut ditiadakan agar Anda dapat fokus memahami bahwa sebenarnya membuat frameworkitu sangatlah mudah.

MembuatFrameworkSederhana 181

Front Controller

Dan berikut adalahfileindex.phpataufront controllerdariframe- workyang kita buat:

1 <?php

2 $loader = require __DIR__.'/../vendor/autoload.php';

3

4 use Symfony\Component\HttpFoundation\Request;

5 use Symfony\Component\HttpFoundation\Response;

6 use BelajarOOP\Framework\Application;

7

8 //Grabing request

9 $request = Request::createFromGlobals();

10

11 //Bootstraping

12 $app = new Application(array('database' => array('host'\

13 => 'localhost')));//Contoh config saja tapi tidak dipa\

14 kai 15

16 //Route register

17 $app->route('/hello/{name}', function ($name) { 18 return new Response(sprintf('Hello %s', $name));

19 });

20

21 //Request handling

22 $response = $app->handle($request);

23

24 //Send response 25 $response->send();

Seperti yang saya sudah saya jelaskan diatas, bahwaframeworkkita sudah jadi. Untuk memastikan kebenaran tersebut, mari kita coba

jalankanframeworktersebut.

Untuk mempermudah dan agar tidak perlu settingvhost dan web server, saya menggunakanbuilt-in web server untuk menjalankan framework kita. Cukup mengetikanphp -S localhost:8000 dari folder webmaka aplikasi kita sudah berjalan.

Berikut adalah tampilancommanduntuk menjalankanweb server:

Built In Web Server

Dan tampilan dariframework kita, ketika ketika mengetikkanlo-

calhost:8000/hello/<Nama>adalah sebagai berikut:

Framework

Bagaimana? Mudah sekali bukan sebenarnya. Untuk langkah se- lanjutnya, kita akan menerapkanobserver patternpadaframework kita agar,frameworkyang kita buat makin fleksibel.

VII. Event Dispatcher

Tahap terakhir dari framework kita adalah menambahkan hook agar framework yang kita buat lebih mudah di-extend. Kita akan

MembuatFrameworkSederhana 183 menggunakanEvent Dispatcher Component yang menerapkanob- server patternuntuk membuathooktersebut.

Sebelum membuathook, mari kita buat terlebih dahuluevent class- nya sebagai berikut:

1 <?php 2

3 namespace BelajarOOP\Framework\Event;

4

5 use Symfony\Component\EventDispatcher\Event;

6 use Symfony\Component\HttpFoundation\Response;

7

8 class FilterResponseEvent extends Event 9 {

10 private $response;

11

12 public function setResponse(Response $response)

13 {

14 $this->response = $response;

15 }

16

17 public function getResponse()

18 {

19 return $this->response;

20 }

21 }

1 <?php 2

3 namespace BelajarOOP\Framework\Event;

4

5 use Symfony\Component\EventDispatcher\Event;

6 use Symfony\Component\HttpFoundation\Request;

7 use Symfony\Component\HttpFoundation\Response;

8

9 class FilterRequestEvent extends Event 10 {

11 private $request;

12

13 private $response;

14

15 public function setRequest(Request $request)

16 {

17 $this->request = $request;

18 }

19

20 public function getRequest()

21 {

22 return $this->request;

23 }

24

25 public function setResponse(Response $response)

26 {

27 $this->response = $response;

28 }

29

30 public function getResponse()

31 {

32 return $this->response;

33 }

34 }

MembuatFrameworkSederhana 185 Selanjutnya adalah kita membuat namaeventpadaclassApplica-

tionsebagai berikut:

1 <?php 2

3 namespace BelajarOOP\Framework;

4

5 use BelajarOOP\Framework\Http\Kernel;

6

7 class Application extends Kernel 8 {

9 const PRE_REQUEST_EVENT = 'kernel.request';

10 const PRE_RESPONSE_EVENT = 'kernel.response';

11

12 protected $configs;

13

14 public function __construct(array $configs = array(\

15 ))

16 {

17 parent::__construct();

18 $this->configs = $configs;

19 }

20

21 public function setConfig($key, $value)

22 {

23 $this->configs[$key] = $value;

24 }

25

26 public function getConfig($key)

27 {

28 if (array_key_exists($key, $this->configs)) { 29 return $this->configs[$key];

30 }

31

32 return null;

33 } 34 }

Tahap terakhir yaitu kita membuat hook untuk framework kita.

Kita perlu membuatnya padaclassKernelpadamethodhandle(). Selain itu, saya juga menambahkanmethodon()padaclassKernel agar bisa dipanggil padaindex.php.

Berikut adalahcode dari classKernelsetelah kita menambahkan event dispatcher:

1 <?php 2

3 namespace BelajarOOP\Framework\Http;

4

5 use BelajarOOP\Framework\Application;

6 use BelajarOOP\Framework\Event\FilterRequestEvent;

7 use BelajarOOP\Framework\Event\FilterResponseEvent;

8 use InvalidArgumentException;

9 use Symfony\Component\EventDispatcher\EventDispatcher;

10 use Symfony\Component\HttpFoundation\Request;

11 use Symfony\Component\HttpFoundation\Response;

12 use Symfony\Component\HttpKernel\HttpKernelInterface;

13 use Symfony\Component\Routing\Exception\ResourceNotFoun\

14 dException;

15 use Symfony\Component\Routing\Matcher\UrlMatcher;

16 use Symfony\Component\Routing\RequestContext;

17 use Symfony\Component\Routing\Route;

18 use Symfony\Component\Routing\RouteCollection;

19

20 class Kernel implements HttpKernelInterface 21 {

22 private $router;

23

24 private $eventDispatcher;

MembuatFrameworkSederhana 187

25

26 public function __construct()

27 {

28 //Symfony Route Collection

29 $this->router = new RouteCollection();

30

31 //Event Dispatcher

32 $this->eventDispatcher = new EventDispatcher();

33 }

34

35 public function handle(Request $request, $type = se\

36 lf::MASTER_REQUEST, $catch = true)

37 {

38 $filterRequest = new FilterRequestEvent();

39 $filterRequest->setRequest($request);

40

41 //Add Filter Query Event

42 $this->eventDispatcher->dispatch(Application::P\

43 RE_REQUEST_EVENT, $filterRequest);

44

45 if ($response = $filterRequest->getResponse()) {

46 return $response;

47 }

48

49 //Request Context

50 $context = new RequestContext();

51 $context->fromRequest($request);

52

53 //Url Matcher

54 $matcher = new UrlMatcher($this->router, $conte\

55 xt);

56

57 try {

58 //Matching Url and Getting Route

59 $attributes = $matcher->match($request->get\

60 PathInfo());

61

62 //Get Controller from Route attribute @see \ 63 `route()` method

64 $controller = $attributes['_controller'];

65

66 unset($attributes['_controller']);

67

68 //Make it simple, use call_user_func_array \ 69 to calling controller and passing attributes as paramet\

70 er

71 $response = call_user_func_array($controlle\

72 r, $attributes);

73

74 $filterResponse = new FilterResponseEvent();

75 $filterResponse->setResponse($response);

76

77 //Add Filter Response Event

78 $this->eventDispatcher->dispatch(Applicatio\

79 n::PRE_RESPONSE_EVENT, $filterResponse);

80

81 $response = $filterResponse->getResponse();

82 } catch (ResourceNotFoundException $e) {

83 $response = new Response('Not found!', Resp\

84 onse::HTTP_NOT_FOUND);

85 }

86

87 return $response;

88 }

89

90 public function route($path, $controller)

91 {

92 if (!is_callable($controller)) {

93 throw new \InvalidArgumentException(sprintf\

94 ('%s is not callable.', $controller));

MembuatFrameworkSederhana 189

95 }

96 $this->router->add($path, new Route(

97 $path,

98 array('_controller' => $controller)

99 ));

100 }

101

102 public function on($event, $callback)

103 {

104 if (! is_callable($callback)) {

105 throw new InvalidArgumentException(sprintf(\

106 '%s is not callable.', $callback));

107 }

108

109 $this->eventDispatcher->addListener($event, $ca\

110 llback);

111 }

112 }

Langkah terakhir adalah, mencoba melakukanhooking pada in-

dex.php untuk menguji bahwa code kita berjalan dengan benar.

Dan berikut adalah file index.php yang sudah kita tambahkan hook:

1 <?php

2 $loader = require __DIR__.'/../vendor/autoload.php';

3

4 use Symfony\Component\HttpFoundation\Request;

5 use Symfony\Component\HttpFoundation\Response;

6 use BelajarOOP\Framework\Application;

7 use BelajarOOP\Framework\Event\FilterRequestEvent;

8

9 //Grabing request

10 $request = Request::createFromGlobals();

11

12 //Bootstraping

13 $app = new Application(array('database' => array('host'\

14 => 'localhost')));//Contoh config saja tapi tidak dipa\

15 kai 16

17 //Route register

18 $app->route('/hello/{name}', function ($name) { 19 return new Response(sprintf('Hello %s', $name));

20 });

21

22 $app->on(Application::PRE_REQUEST_EVENT, function (Filt\

23 erRequestEvent $event) {

24 if ('/admin' === $event->getRequest()->getPathInfo(\

25 )) {

26 $event->setResponse(new Response('Anda harus lo\

27 gin sebagai admin untuk mengakses halaman ini.'));

28 }

29 });

30

31 //Request handling

32 $response = $app->handle($request);

33

34 //Send response 35 $response->send();

Jadi ceritanya, kita akan mencoba membatas akses padaurl/admin. Ketika kita mengakses halaman tersebut, maka akan muncul pesan

Anda harus login sebagai admin untuk mengakses halaman ini.. Untuk memastikan bahwahookkita bekerja sebagaimana mestinya, mari kita buka kembali browser dan mengakses alamat local-

host:8000/admin. Jika benar, maka akan muncul pesan seperti diatas sebagai berikut:

MembuatFrameworkSederhana 191

Hooking Framework

Bagaimana? Mudah sekali bukan? Ternyata membuat framework tidak sesulit yang kita bayangkan. Anda dapat mencoba den- gan menggunakan PRE_RESPONSE_EVENTuntuk lebih meyakinkan bahwaframeworktelah bekerja sesuai dengan yang kita inginkan.

VIII. Kesimpulan

Dengan menguasai OOP, membuatframeworksederhana tidaklah sulit. Bahkanframeworkyang kita buatpun tidak perlu banyakclass untuk membuatnya.

Saya tidak menyarankan Anda menggunakanframeworkyang kita buat untukproject realAnda tanpa ada perbaikan dan penambahan validasi padaframework.

Framework masih sangat premature sehingga perlu banyak per- baikan dan penambahan disana-sini agar semakinpowerful.

Dalam dokumen Buku Belajar Santai OOP PHP (Halaman 187-199)

Dokumen terkait