└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # PHP'den NodeJS'e Geçiş 2 | 3 | Bildiğiniz gibi yıllardır PROTOTURK youtube kanalında PHP programlama dili ile ilgili içerikler ürettim. Biraz da NodeJS içerikleri üretmek istediğim için ve kanalın neredeyse tamamı PHP geliştirdiği için PHP'den NodeJS'e soft bir geçiş için bir rehber hazırlamak istiyorum. 4 | 5 | Aynı zamanda zaten bu işlemi videolu olarak yapıyoruz, burada da yazılı kalsın. 6 | 7 | ## Gereksinimler 8 | 9 | Bu rehber sizin PHP'yi zaten bildiğinizi ve temel JavaScript'e hakim olduğunuzu kabul eder. O yüzden değişkenler, fonksiyonlar, döngüler, diziler, nesneler gibi kavramları ele almadan NodeJS ve Express ile web uygulamaları geliştirmeye odaklanır. 10 | 11 | Ancak elbette bazı durumlarda PHP'de nasıldı, NodeJS'de nasıl gibi sorulara cevap vereceğimiz bölümler olacak. 12 | 13 | ## Hello World! 14 | 15 | ### PHP 16 | 17 | PHP'de bir işleme başlamak istediğinizde `.php` uzantılı bir dosya açıp `echo` ile bir çıktı verebiliyorsunuz. , 18 | 19 | ```php 20 | bu bize bir `package.json` dosyası oluşturuyor. NPM node'un paket yöneticisi, PHP'deki composer gibi düşünebilirsiniz. `package.json` ise php'deki `composer.json` gibi düşünebilirsiniz. 34 | 35 | Daha sonra bir `app.js` dosyası oluşturup şu kodları yazın: 36 | 37 | ```js 38 | console.log('Hello, world!') 39 | ``` 40 | 41 | Ve çalıştırıp test edin: 42 | 43 | ```shell 44 | node app.js 45 | ``` 46 | 47 | Elbete, PHP'de yazılanı tarayıcıda, NodeJS'de yazılanı konsol'da görüyoruz şu an. O yüzden biraz daha anlamlı örnek verelim. 48 | 49 | ## Routing Islemleri 50 | 51 | ### PHP 52 | 53 | PHP'de routing işlemleri için bir sürü paket var kullanabileceğimiz. Ama temelde aslında URL'i parse ederek hangi alanda hangi kodun çalıştıracağını söylüyoruz. Örneğin: 54 | 55 | ```php 56 | Route::get('/', function() { 57 | return 'anasayfa' 58 | }); 59 | 60 | Route::get('/iletisim', '\Controllers\Contact'); 61 | 62 | Route::get('/user/:url', '\Controllers\User\Detail'); 63 | ``` 64 | 65 | gibi. Tabi bu kod doğrudan çalışmaz ancak PHP developer olarak ne demek istediğimi anladınız bence :D 66 | 67 | ### NodeJS 68 | 69 | NodeJS'de web uygulamaları geliştirilirken en yaygın kullanılan `express` çatısı. Elbette bir sürü alternatifi var ama soft geçişte sanırım en mantıklısı bu. Dolayısı ile routing'ler ile çalışmak için ilk olarak `express` paketini kuralım. 70 | 71 | ```shell 72 | npm i express 73 | ``` 74 | 75 | Ve daha sonra `app.js` dosyamızı şöyle güncelleyelim. 76 | 77 | ```js 78 | import express from "express" 79 | 80 | const app = express() 81 | 82 | app.get('/', (req, res) => { 83 | res.send('anasayfa') 84 | }) 85 | 86 | app.get('/iletisim', (req, res) => { 87 | res.send('iletisim') 88 | }) 89 | 90 | app.listen(3000, () => console.log('Uygulama 3000 portundan dinleniyor')) 91 | ``` 92 | 93 | Ve bunu çalıştıralım. 94 | 95 | ```shell 96 | node app.js 97 | ``` 98 | 99 | Artık `http://localhost:3000` ve `http://localhost:3000/iletisim` adreslerinden yazdığınız kodları görebilirsiniz. 100 | 101 | Bir başka örnekte dinamik değerleri almakla ilgili olsun. Örneğin `/user/tayfunerbilen` adresine girdiğimizde `tayfunerbilen` değeri dinamik olacağı için bunu almak gerekiyor. Onun içinde şöyle bir route ekleyebilirdik: 102 | 103 | ```js 104 | app.get('/user/:slug', (req, res) => { 105 | res.send('hoşgeldin ' + req.params.slug) 106 | }) 107 | ``` 108 | 109 | Burada `:slug` olarak belirttiğimiz değeri `req.params` içinde `slug` olarak erişebiliyor. Yani buraya `:adana` yazsaydım `req.params.adana` olarak alıp kullanacaktım. 110 | 111 | ## HTML ile Kullanımı 112 | 113 | ### PHP 114 | 115 | Elbette php'nin html'e gömülebilen bir dil olduğunu biliyoruz. Örneğin: 116 | 117 | ```php 118 | 119 | $title = 'deneme baslik'; 120 | $content = 'deneme content'; 121 | 122 | require __DIR__ . '/home.php/'; 123 | ``` 124 | 125 | ve `home.php` şöyle olsun: 126 | 127 | ```php 128 | 129 | 130 | 131 | 132 | <?=$title?> 133 | 134 | 135 | 136 |
137 | 138 |
139 | 140 | 141 | 142 | ``` 143 | 144 | ### NodeJS 145 | 146 | Bunun nodejs karşılığında birden fazla alternatif template engine olsada ben EJS ile örneğini göstereceğim çünkü PHP yazan birisine çok daha yakın hissettiriyor :D Önce paketi kuralım: 147 | 148 | ```shell 149 | npm i ejs 150 | ``` 151 | 152 | Daha sonra express'de template engine olarak `ejs` kullanacağımızı söyleyelim. 153 | 154 | ```js 155 | app.set('view engine', 'ejs') 156 | ``` 157 | 158 | ve `views` klasörü oluşturup içine bir tane `index.ejs` dosyası açalım. Evet `ejs` kodlarımızı `.ejs` uzantılı dosyada yazıyoruz :D 159 | 160 | ```html 161 | 162 | 163 | 164 | 165 | <%=title%> 166 | 167 | 168 | 169 |
170 | <%=content%> 171 |
172 | 173 | 174 | 175 | ``` 176 | 177 | son olarakta bunu `/` anasayfaya girdiğinde render edelim. 178 | 179 | ```js 180 | app.get('/', (req, res) => { 181 | res.render('index', { 182 | title: 'Site Basligi', 183 | content: 'Hosgeldin gardas!' 184 | }) 185 | }) 186 | ``` 187 | 188 | sonuç olarak `localhost:3000` adresine girdiğimizde dinamik değerleri güzel bir şekilde kullandığımız ve php'den çokta farklı olmadığını göreceksiniz kullanımın. 189 | 190 | ### Static Dosyalar 191 | 192 | PHP'de tarayıcıdan bir dosyaya erişmek için ek bir ayar yapmanıza gerek yok. Ancak bir nodejs projesinde bunun ayarını express çatısını kullanıyorsak şöyle yapıyoruz: 193 | 194 | ```js 195 | app.use('/assets', express.static('assets')) 196 | ``` 197 | 198 | böylece `assets` içinde css, image, js gibi dosyaları tutabilir ve erişebilirsiniz. Örneğin dosyalar yüklendiği `upload` klösörünü de 2. bir tanımla ayarlayabilirsiniz. 199 | 200 | ```js 201 | app.use('/upload', express.static('upload')) 202 | ``` 203 | 204 | ### Form Validasyon İşlemleri 205 | 206 | Validasyon işlemleri için kullanabileceğiniz bir sürü paket mevcut. Ben bunların arasından `express-validator` paketini kullanmaya karar verdim. 207 | 208 | Kurmak için: 209 | 210 | ```shell 211 | npm i express-validator 212 | ``` 213 | 214 | Kullanırkende, validasyon işlemi yapacağınız route'da middleware mantığında kullanıyorsunuz. Örneğin `username`, `email`, `password` ve `passwordConfirmation` alanlarına sahip form değerlerimiz olsun. Bunların kontrolünü `/register` post işleminde kontrol edelim. 215 | 216 | ```js 217 | import { body, validationResult } from 'express-validator'; 218 | 219 | // diger app kodlari 220 | 221 | app.post( 222 | '/register', 223 | [ 224 | // Kullanıcı adı en az 3 karakter olmalı ve alfanümerik olmalıdır. 225 | body('username') 226 | .isLength({ min: 3 }) 227 | .withMessage('Kullanıcı adı en az 3 karakter olmalıdır.') 228 | .isAlphanumeric() 229 | .withMessage('Kullanıcı adı sadece alfanümerik karakterler içermelidir.'), 230 | 231 | // E-posta geçerli olmalıdır. 232 | body('email') 233 | .isEmail() 234 | .withMessage('Geçerli bir e-posta adresi girin.'), 235 | 236 | // Şifre en az 6 karakter uzunluğunda olmalıdır. 237 | body('password') 238 | .isLength({ min: 6 }) 239 | .withMessage('Şifre en az 6 karakter uzunluğunda olmalıdır.'), 240 | 241 | // Şifre ve şifre doğrulama alanları eşleşmelidir. 242 | body('passwordConfirmation').custom((value, { req }) => { 243 | if (value !== req.body.password) { 244 | throw new Error('Şifre doğrulama eşleşmiyor.'); 245 | } 246 | return true; 247 | }), 248 | ], 249 | (req, res) => { 250 | const errors = validationResult(req); 251 | if (!errors.isEmpty()) { 252 | return res.status(400).json({ errors: errors.array() }); 253 | } 254 | 255 | // Veriler doğrulandıktan sonra kayıt işlemi gerçekleştirin. 256 | const { username, email, password } = req.body; 257 | res.send(`Kullanıcı ${username} başarıyla kaydedildi.`); 258 | } 259 | ); 260 | ``` 261 | 262 | ## Oturum Yönetimi (SESSION) 263 | 264 | Oturum yönetimi için `express-session` paketini kullanıyoruz. Önce paketi kuralım: 265 | 266 | ```shell 267 | npm i express-session 268 | ``` 269 | 270 | daha sonra `app.js` de yani main javascript dosyanızda bunu içeri alın. 271 | 272 | ```js 273 | import session from "express-session" 274 | ``` 275 | 276 | ve kullanırken `express` de middleware olarak şöyle kullanın: 277 | 278 | ```js 279 | app.use( 280 | session({ 281 | secret: 'benzersiz_bir_anahtar', // session sifrelemesi icin 282 | resave: false, 283 | saveUninitialized: true 284 | }) 285 | ) 286 | ``` 287 | 288 | artık routing'de `req` altında `req.session` olarak session'lara erişebilir ya da yeni session'lar tanımlayabilirsiniz. Örneğin: 289 | 290 | ```js 291 | app.get('/', (req, res) => { 292 | req.session.user_id = 3 // artik session islemim basladi 293 | }) 294 | ``` 295 | 296 | oturumu sonlandırmak içinde `destroy()` metodunu kullanabilirsiniz. Örneğin: 297 | 298 | ```js 299 | app.get('/logout', (req, res) => { 300 | req.session.destroy() // oturum sonlandırıldı 301 | }) 302 | ``` 303 | --------------------------------------------------------------------------------