Adım Adım Sıfırdan Laravel Websitesi Oluşturma

Bayram EKER
9 min readFeb 3, 2022

--

Yeni başlayan biriyseniz ve Laravel uygulamaları geliştirmeye nasıl başlayacağınızı öğrenmek istiyorsanız doğru yere geldiniz çünkü bugün adım adım ilk Laravel 5.6 projenizi nasıl oluşturacağınızı öğreneceğiz. Şunları öğreneceksin:

  • İlk Laravel projenizi nasıl oluşturabilirsiniz ?
  • Gönderiler nasıl oluşturulur ?
  • Gönderiler nasıl düzenlenir ?
  • Gönderiler nasıl silinir ?

İlk Laravel projenizi nasıl oluşturabilirsiniz?

Laravel Framework’ü, uygulamalarınızı sorunsuz bir şekilde geliştirmek için gerekli olan birkaç sistem gereksinimine sahiptir. Farklı paketler kurmak konusunda rahat değilseniz, tüm işi sizin yerinize yapan ve yerel gelişiminizi kolaylaştıran Laravel Homestead sanal makinesini kullanmanızı şiddetle tavsiye ederiz.

Ancak, Homestead kullanmıyorsanız sunucunuzun aşağıdaki gereksinimleri karşıladığından emin olmanız gerekir:

  • PHP >= 7.1.3
  • OpenSSL PHP Extension
  • PDO PHP Extension
  • Mbstring PHP Extension
  • Tokenizer PHP Extension
  • XML PHP Extension
  • Ctype PHP Extension
  • JSON PHP Extension

Laravel, bağımlılıklarını yönetmek için Composer’ı kullanır. Bu nedenle, Laravel’i kullanmadan önce makinenizde Composer’ın kurulu olduğundan emin olun.

Öncelikle, Composer kullanarak Laravel yükleyicisini indirmeniz gerekecek. Terminalinizde şu komutu çalıştırın:

$ composer global require "laravel/installer"

İndirme tamamlandıktan sonra artık yeni Laravel kurulumunuzu oluşturabilirsiniz:

$ laravel new blog

Blog kelimesi, Laravel projesinin hangi dizine kurulacağını belirtir. Laravel projesini kurmanın alternatif yöntemi, Composer komutunu kullanmak olacaktır:

$ composer create-project --prefer-dist laravel/laravel blog

PHP’yi yerel olarak yüklediyseniz ve uygulamanızı sunmak için yerleşik geliştirme sunucusunu kullanmak istiyorsanız, sunucunuzu http://localhost:8000 adresinde kullanıma sunacak php artisan serve komutunu kullanabilirsiniz.

Projenizi kurduktan sonra yapmanız gereken bir sonraki şey, uygulama anahtarınızı rastgele bir dizeye ayarlamaktır. Bunu, bu komutu terminalde yazarak yapabilirsiniz:

$ php artisan key:generate

Veritabanınızı yapılandırmak istiyorsanız, projenizin kök dizininde .env dosyasını açabilir ve veritabanı kimlik bilgilerinizi ekleyebilirsiniz:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=secret

Artık ilk Laravel uygulamanızı oluşturmaya hazırsınız. Bu örnek için, gönderiler oluşturabileceğiniz, görüntüleyebileceğiniz, düzenleyebileceğiniz ve silebileceğiniz basit bir blog oluşturacağız.

Gönderiler nasıl oluşturulur ?

Öncelikle bir Post model oluşturmamız gerekiyor. Bu model veritabanı tablomuzu temsil edecek ve onunla iletişim kurmak için kullanılacaktır. Laravel’de basitçe bir model oluşturmak için bunu terminalde yazabiliriz:

$ php artisan make:model Post -m

-m veya — migration seçeneği, database/migrations klasöründe bulabileceğimiz bir migration dosyası da oluşturacak şekilde ayarlanmıştır. Yeni oluşturulan bu dosyayı açıp tablomuzun sütunlarını belirtebiliriz:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->text('description');
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}

Dosyayı kaydettikten sonra artık her şeyi veritabanına taşıyabiliriz:

$ php artisan migrate

Artık bir post controller oluşturabilir ve bazı fonksiyonları belirtebiliriz:

$ php artisan make:controller PostController -r

-r seçeneği bize biraz zaman kazandırır ve temel CRUD işlevlerini oluşturur. CRUD’nin ne olduğunu bilmiyorsanız, Oluştur, Oku, Güncelle ve Sil işlevidir. Artık app/Http/Controller/PostController.php dosyamıza gidebilir ve dizin işlevi oluşturabilir ve görünümü döndürebiliriz:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PostController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
return view('post.index');
}
...

Görünümümüzü resources/views klasöründe tanımlayabiliriz. Bu durumda, welcome.blade.php dosyasını index.blade.php olarak yeniden adlandıracağız ve post adında yeni bir klasör oluşturacağız ve index.blade.php dosyasını bu klasöre taşıyacağız. Şimdi bu resources/views/post/index.blade.php gibi bir yolunuz olmalıdır. Şimdi düzeni biraz değiştireceğiz:

<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title>{{ config('app.name') }}</title>

<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet" type="text/css">

<link rel="stylesheet" href="{{ asset('css/app.css') }}">
</head>

<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="{{ route('post.index') }}">{{ config('app.name') }}</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>

<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="{{ route('post.index') }}">Home <span class="sr-only">(current)</span></a>
</li>
</ul>

<a href="{{ route('post.create') }}" class="btn btn-success my-2 my-sm-0">Create Post</a>
</div>
</nav>
<div class="container py-3">
<div class="row">
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h3>Post Title</h3>
</div>
<div class="card-body">
<p>Post Description</p>
<a href="#" class="btn btn-primary btn-block">Read More</a>
</div>
</div>
</div>
</div>
</div>
</body>

</html>

Son olarak, gönderi görünümlerimiz için rotaları tanımlamamız gerekiyor. Bunu route/web.php dosyasını düzenleyerek ve şunu ekleyerek yapabiliriz:

Route::resource('post', 'PostController');

Kullanmak istediğimiz bir URL adı ve bir denetleyici(controller) belirledik. Artık http://localhost:8000/post adresini ziyaret ettiğimizde yeni oluşturduğumuz görünümümüzü görebiliriz. Hangi Route::resource(), ihtiyacımız olan tüm rotaları ouşturur, böylece terminalinizde çalıştırırsanız:

$ php artisan route:list

+--------+-----------+------------------+--------------+---------------------------------------------+--------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+-----------+------------------+--------------+---------------------------------------------+--------------+
| | GET|HEAD | api/user | | Closure | api,auth:api |
| | GET|HEAD | post | post.index | App\Http\Controllers\PostController@index | web |
| | POST | post | post.store | App\Http\Controllers\PostController@store | web |
| | GET|HEAD | post/create | post.create | App\Http\Controllers\PostController@create | web |
| | GET|HEAD | post/{post} | post.show | App\Http\Controllers\PostController@show | web |
| | PUT|PATCH | post/{post} | post.update | App\Http\Controllers\PostController@update | web |
| | DELETE | post/{post} | post.destroy | App\Http\Controllers\PostController@destroy | web |
| | GET|HEAD | post/{post}/edit | post.edit | App\Http\Controllers\PostController@edit | web |
+--------+-----------+------------------+--------------+---------------------------------------------+--------------+

Tüm gerekli yöntemler ve tanımlanmış denetleyici eylemlerine sahip rotalar(routerler) olduğunu göreceksiniz.

Şimdi ilk dinamik gönderimizi oluşturalım. Her şeyden önce, post controller’ımızda yeni bir controller fonksiyonu oluşturacağız:

...
public function create()
{
return view('post.create');
}
...

Şimdi görünümümüzü oluşturmamız gerekiyor. Resources/view/post klasörümüzde create.blade.php dosyası oluşturacağız. Gönderimizin verilerini depolamak için kullanacağımız basit bir form oluşturacağız:

<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title>{{ config('app.name') }}</title>

<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet" type="text/css">

<link rel="stylesheet" href="{{ asset('css/app.css') }}">
</head>

<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="#">{{ config('app.name') }}</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>

<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
</ul>

<a href="{{ route('post.create') }}" class="btn btn-success my-2 my-sm-0">Create Post</a>
</div>
</nav>
<div class="container py-3">
<div class="row">
<div class="col-md-8 offset-md-2">
<form method="POST" action="{{ route('post.store') }}">
@csrf

<div class="form-group">
<label for="title">Title</label>
<input type="text" name="title" class="form-control" value="{{ old('title') }}"
placeholder="Post title">
</div>

<div class="form-group">
<label for="description">Description</label>
<textarea name="description" rows="8" cols="80"
class="form-control">{{ old('description') }}</textarea>
</div>

<button type="submit" class="btn btn-primary">Create Post</button>
</form>
</div>
</div>
</div>
</body>
</html>

Form için zaten bir eylem URL’si yazdığımı görebilirsiniz. Ayrıca, formdan hemen sonra @csrf kodu içeren bir satır olduğunu da görebilirsiniz. Bu Blade sözdizimidir ve formları Laravel’de göndermek için gerekli olan gizli bir belirteç alanı oluşturur. Ayrıca giriş alanları değer özelliğinde {{ old('title') }} olduğunu görebilirsiniz. Form gönderildiğinde ve reddedildiğinde kullanılır, eski form değerlerini koyar, böylece tüm değerleri tekrar girmemize gerek kalmaz.

PostController.php dosyasına mağaza fonksiyonumuzu yazmamız gerekiyor:

...
public function store(Request $request)
{
$validatedData = $this->validate($request, [
'title' => 'required|min:3|max:255',
'description' => 'required|min:3'
]);

Post::create($validatedData);

return redirect()->route('post.index');
}
...

Öncelikle formumuzdaki verileri doğrularız. Ardından, yeni bir Post modelini tek satırda kaydetmek için create yöntemini kullanırız. Ancak, tüm Eloquent modelleri varsayılan olarak toplu atamaya karşı koruma sağladığından, bunu yapmadan önce modelde doldurulabilir veya korumalı bir öznitelik belirtmeniz gerekir. Şimdi app/Post.php dosyamıza gidelim ve içeri şunu ekleyelim:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
protected $fillable = ['title', 'description'];
}

Controller store() yöntemimize geri dönersek, sonunda kullanıcıyı ana sayfaya yönlendiririz. Ayrıca Post modelini denetleyiciye eklemeyi de unutmayın:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Post;

class PostController extends Controller
{
...

Her şeyi doğru yaptıysanız, şimdi bir gönderi oluşturabilmeniz gerekir. Gönderi oluşturma sayfanıza gidin, formu doldurun ve gönderin. Sayfa ana sayfaya yönlendiriliyorsa, muhtemelen gönderinizi veritabanına kaydetmişsinizdir. Şimdi indeks sayfasındaki tüm gönderileri görüntülememiz gerekiyor. Bunu PostController.php dizin işlevinde yapabiliriz:

...
public function index()
{
$posts = Post::all();

return view('post.index')->withPosts($posts);
}
...

Tüm tablo gönderi girişlerini alır ve ana dizin görünümüne(view) döndürürüz. index.blade.php dosyamızda tüm kayıtlarımızı görüntülemek için bir foreach döngüsü oluşturmamız gerekiyor:

<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title>{{ config('app.name') }}</title>

<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet" type="text/css">

<link rel="stylesheet" href="{{ asset('css/app.css') }}">
</head>

<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="{{ route('post.index') }}">{{ config('app.name') }}</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>

<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="{{ route('post.index') }}">Home <span class="sr-only">(current)</span></a>
</li>
</ul>

<a href="{{ route('post.create') }}" class="btn btn-success my-2 my-sm-0">Create Post</a>
</div>
</nav>
<div class="container py-3">
<div class="row">
@foreach($posts as $post)
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h3>{{ $post->title }}</h3>
</div>
<div class="card-body">
<p>{{ substr($post->description, 0, 100) }}</p>
<a href="{{ route('post.show', $post->id) }}" class="btn btn-primary btn-block">Read More</a>
</div>
</div>
</div>
@endforeach
</div>
</div>
</body>

</html>

Foreach döngüsü için Blade söz dizimini kullandık ve $posts değişkenini geçtik ve tek bir nesneyi $post olarak tanımladık. Şimdi foreach döngüsü içindeki tüm içerik, tüm $posts nesneleri geçilene kadar devam edecek. Ve nesnenin verilerine şu $post->title gibi erişebiliriz. Açıklama için, kaç karakterin görüntüleneceğini tanımlayan substr() php işlevini kullandık. Ayrıca, post.show görünümümüze bağlayacağımız bir ‘Daha Fazla Oku’ düğmesi tanımladık. Bir post.show rotası için, kontrolöre hangi gönderinin gösterileceğini söyleyen posta kimliğini geçmemiz gerekiyor. Alternatif olarak, denetleyicinin hangi nesneyi göstereceğini bilmesini sağlamak için bir gönderi bilgisi iletebilirsiniz. Sümüklü böcekler hakkında daha fazla bilgi edinmek için Laravel’de Sümüklü böcek Nasıl Oluşturulur hakkındaki diğer eğitimimi okuyabilirsiniz.

Bunu yaptıktan sonra, bu gönderiyi bir veritabanında bulmamız ve gönderi denetleyicimizin işlev şovundaki post.show görünümüne döndürmemiz gerekiyor:

...
public function show(Post $post)
{
return view('post.show')->withPost($post);
}
...

Ve son olarak, show.blade.php adlı kaynaklarda/görünümlerde/yazıda yeni görünümümüzü oluşturabiliriz:

<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title>{{ config('app.name') }}</title>

<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet" type="text/css">

<link rel="stylesheet" href="{{ asset('css/app.css') }}">
</head>

<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="{{ route('post.index') }}">{{ config('app.name') }}</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>

<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="{{ route('post.index') }}">Home <span class="sr-only">(current)</span></a>
</li>
</ul>

<a href="{{ route('post.create') }}" class="btn btn-success my-2 my-sm-0">Create Post</a>
</div>
</nav>
<div class="container py-3">
<div class="row">
<div class="col-md-8 offset-md-2">
<div class="card">
<div class="card-header">
<h1>{{ $post->title }}</h1>
</div>

<div class="card-body">
<p>{{ $post->description }}</p>

<a href="{{ route('post.edit', $post->id) }}" class="btn btn-primary">Edit Post</a>
</div>
</div>
</div>
</div>
</div>
</body>

</html>

Artık bir nesne koleksiyonu yerine yalnızca bir nesneye sahip olduğumuz için foreach döngüsünü kullanmadığımızı görebiliriz. Gönderi bilgilerimizi şu şekilde görüntüleyebiliriz {{ $post->title }}.

Gönderiler nasıl düzenlenir ?

Muhtemelen zaten yeni bir rota ile bir ‘Gönderiyi Düzenle’ düğmesi oluşturduğumu fark etmişsinizdir. Bu rota yazımızı düzenlemek için kullanılacaktır. Aynı ‘Daha Fazla Oku’ butonu ile aynı şekilde, gönderimizin kimliğini rotaya iletmemiz gerekiyor.

Şimdi, denetleyicimizde post nesnesiyle post.edit görünümünü döndürebiliriz:

...
public function edit(Post $post)
{
return view('post.edit')->withPost($post);
}
...

Aslında create.blade.php dosyasını çoğaltabilir ve onu edit.blade.php olarak yeniden adlandırabiliriz. Sadece birkaç şeyi değiştirmemiz gerekiyor:

...
<div class="card">
<div class="card-header">
<h1>Edit Post</h1>
</div>

<div class="card-body">
<form method="POST" action="{{ route('post.update', $post->id) }}">
@csrf
@method('PUT')

<div class="form-group">
<label for="title">Title</label>
<input type="text" name="title" class="form-control" value="{{ $post->title }}">
</div>

<div class="form-group">
<label for="description">Description</label>
<textarea name="description" rows="8" cols="80" class="form-control">{{ $post->description }}</textarea>
</div>

<button type="submit" class="btn btn-primary">Update Post</button>
</form>
</div>
</div>
...

Form eylem rotasını değiştirdik ve alanlardaki verileri görüntülemek için {{ old(‘title’) }} yerine {{ $post->title) }} yazabiliriz. Post.update rotasının PUT yöntemini kullandığı akılda tutulması gereken başka bir şey de, çalışması için @csrf’ye benzer şekilde, Laravel’in bize izin vermesi için yöntem değerine sahip gizli bir alan oluşturan @method(‘PUT’) koymamız gerekir. bu formu gönderin.

Şimdi denetleyici dosyamıza geri dönebiliriz ve güncelleme işlevi için şunu koyabiliriz:

...
public function update(Request $request, Post $post)
{
$validatedData = $this->validate($request, [
'title' => 'required|min:3|max:255',
'description' => 'required|min:3'
]);

$post->update($validatedData);

return redirect()->route('post.show', $post);
}
...

Bu yöntemin mağaza işleviyle hemen hemen aynı olduğunu görebilirsiniz. Tek fark, yeni Post örneğini oluşturmamıza gerek yok, veritabanımızda mevcut bir nesneyi bulmamız ve onu güncellememiz gerekiyor.

Her şeyi doğru yaptıysanız, şimdi yayınınızı güncelleyebilmelisiniz. Kapatmamız gereken son şey gönderiyi silmek.

Gönderiler nasıl silinir ?

show.blade.php dosyasına yeni bir rota ile ‘Sil’ adlı ek bir düğme ekleyebiliriz. ‘Gönderiyi Düzenle’ düğmesi arasındaki fark, form aracılığıyla göndermemiz ve DELETE yöntemini tanımlamamız gereken bir rotayı basitçe iletmememizdir:

...
<div class="card-body">
<p>{{ $post->description }}</p>

<a href="{{ route('post.edit', $post->id) }}" class="btn btn-primary">Edit Post</a>
<form action="{{ route('post.destroy', $post->id) }}" method="post">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger mt-3">Delete</button>
</form>
</div>
...

Ve son olarak, PostController.php dosyamızın içine bir yok etme işlevi için bir mantık yazmamız gerekiyor:

...
public function destroy(Post $post)
{
$post->delete();

return redirect()->route('post.index');
}
...

Ve bu kadar! Artık gönderilerinizi silebilmelisiniz.

Tebrikler! Artık ilk Laravel uygulamanızı oluşturdunuz. Biraz bunaltıcı olabileceğini biliyorum ama bir kez anladığınızda aslında birçok şeyin kendini tekrar ettiğini görebiliyorsunuz. Bir rota oluşturursunuz, ardından denetleyici dosyanızda bu rotanın ne yaptığını tanımlarsınız ve ardından içeriğinizi görüntülemek için bir görünüm oluşturursunuz. Kaynak kodunu görmek isterseniz buradan yapabilirsiniz. Depoyu terminalinizde klonladıktan sonra, bu öğreticinin sonuna ulaşmak için bu komutu çalıştırabilirsiniz:

$ git checkout create-project -b <your-branch-name>

Herhangi bir sorununuz varsa veya sadece sorularınız varsa, aşağıya yorum yapmaktan çekinmeyin.

--

--

Responses (1)