PHP OOP (Nesne Yönelimli Programlama)

OOP Nedir ve Neden Gereklidir

OOP, bir tasarım modelidir. Tasarım derken grafik olarak değil, kodların tasarımıdır. OOP kavramı şu ihtiyaçlardan dolayı doğmuştur: Eğer bir kod yığınını sürekli olarak kullanıyorsanız, aynı işlemi yapan kodu her projenizde tek tek yazmanıza veya kopyalayıp yapıştırarak modifiye etmek bir angaryadır, vakit kaybıdır. Bunun yerine OOP mantığı ile bir Class oluşturup, bu Class’ta sadece istediğiniz işi yapacak olan fonksiyonlara (Class içindeki fonksiyonlar metot olarak adlandırılır) gerekli parametreleri göndererek rahatlıkla çalışabilirsiniz. Mesela bir e-mail gönderme sınıfınız varsa, bir e-mail gönderme Class’ı hazırlarsınız ve bu Class’a sadece alıcı adresi, mesaj, başlık gibi bilgileri argüman olarak gönderirsiniz. Aynı Class’ı istediğiniz kadar istediğiniz projede kullanabilirsiniz. Oluşturulan bir Class belirli tasarım standartlarına göre hazırlanır. Yani benim hazırladığım, sizin hazırladığınız veya dünyanın bir başka yerinde başka birinin hazırladığı Class’ın kullanım mantığı hemen hemen birbiri ile aynıdır. Yani OOP globaldir. Bu nedenle bir başkasının hazırlayıp kullanımımıza sunduğu Class’ı rahatlıkla kullanabiliriz. Hatta bu Class’lar bir araya gelir ve daha önce işlemiş olduğumuz Framework’leri oluşturur. Yani Framework’ler birer Class yığınıdır. Programlama dünyasında şöyle bir söz vardır: En iyi kod, en kısa koddur. OOP’ tam da bu mantığa hizmet ediyor. Sizin daha az zamanda, daha verimli bir şekilde ve daha kısa kod yazmanızı sağlıyor. OOP’nin diğer bir faydası da kompleks, yani karmaşık projelerde çalışırken sağlamış olduğu kodlama hakimiyetidir. Kodlarınızı OOP ile Class’lara ayırmanız, hiyerarşi sağlar. Ayrıca ekip olarak çalışıyorsanız, birisi bir iş için Class geliştirirken, diğeri de başka bir iş için Class geliştirebilir. Sonra da Class’lar bir araya getirilip rahatlıkla kullanılabilir. Kısacası modüler programlama yapmanızı sağlar.

Sınıf (Class)

Class, en basit tanımı ile birden çok fonksiyonu bir arada bulunduran yapı anlamına gelmektedir. Her Class belli bir konu temasına göre hazırlanır. Mesela bir Class sadece ziyaretçilerin üyelik işlemlerini yapmak için yazılırken, başka bir Class da form üzerindeki verileri doğrulamak için yazılabilir. Bir Class tanımlanırken, o Class için isim vermek de son derece önemlidir. Aşağıda, 3 farklı isim verme metodu kullanılmaktadır (Pascal metoduna göre). classUyelik.php uyelik_class.php uyelik.class.php Bu yazılan isimlerin her biri mantıklı birer isimdir, yani sorunsuz kullanılabilir. Ancak bunlardan üçüncü olan, yani uyelik.class.php daha doğru bir kullanımdır. Eğer kodlarınızı başkalarıyla da paylaşacaksanız bu tür isimlendirmelere dikkat edin, standartlara uyun. Bir başkası bu dosyaya uzaktan baktığında, üyelik işlemlerini yapan bir Class olduğunu rahatlıkla anlayabilmelidir. Bir Class oluşturma sözdizimi şöyledir:

Gördüğünüz gibi bir Class tanımlamak için class anahtar kelimesi kullanılıyor. Ardından Class’ın ismi yazılıp (Class isimleri büyük harfle başlar) süslü parantezler içinde metotlar, yani alt fonksiyonlar yazılıyor. Şimdi bir örnekle inceleyelim…

Yukarıda, Merhaba adında bir Class tanımladık. Bu Class içinde de MerhabaDe() isimli bir metot oluşturduk. Bu dosyayı da kaydedecek olursak; merhaba.class.php ismi ile kaydedebiliriz.

Sınıftan Obje (Object) Tanımlama

Bir Class’ı kullanabilmek için onu mutlaka bir Object nesnesine dönüştürmemiz gerekir. Aynı örnek üzerinden devam edelim…

Evet, işte bu kadar basit bir şekilde Object oluşturduk. Objemizin ismi $selamlamaMesaji şeklindedir. Artık Class’ımıza bu nesne üzerinden erişeceğiz. Class’ı tanımlarken de new anahtar sözcüğüne ve Class isminden sonra gelen () operatörüne dikkat edin.

Metotlar ve Özellikler (Properties)

Şu an elimizde bir Class’ımız ve bu Class’tan üretilmiş bir Object var. Şimdi de Class içindeki merhabaDe() fonksiyonuna erişelim… Metot Tanımlama

Class’tan ürettiğimiz objemizin isminden sonra -> (- ve > işaretleri) ile o nesne içindeki fonksiyona erişilebiliyoruz. Operatörden sonra da metot adını yazmamız yeterli olacaktır. Bu kodu çalıştırdığımızda, bize “Merhaba” diyecektir. Şimdi bir de parametre alan bir metot üzerinde çalışalım. Metot Üzerindeki Özelliğe Erişim

Burada gördüğünüz gibi metodumuza bir parametre ekledik. Parametre değişkenimiz $isim’dir. $isim parametresine de Uğur argümanı gönderilerek metot çağırılıyor. merhabaDe(); metodumuz içinde gelen parametreye erişebilmek için $this anahtar kelimesinden sonra -> operatörü ekleniyor. Sonrasında da metodun içindeki parametre adı girilir. Yani metot içinde, eskisi gibi doğrudan değişken tanımlanamıyor. Bu metot ile fonksiyonun değerinin alacağı belirtiliyor. Bu kod bloğunu çalıştırdığımızda bize “Merhaba Uğur” diyecektir.

Yapıcı ve Yıkıcı Metotlar (__construct() ve __destruct())

Bir Class çağırıldığında, onun hemen işlem yapmasını isteyebiliriz. Class ile işimiz bittiğinde de yine başka bir işlem yapmasını isteyebiliriz. Bu işlemlerde yapıcı ve yıkıcı dediğimiz sihirli fonksiyon tanımlamaları devreye girer. Az önce Class içindeki metodumuzu çalıştırmak için bir Object oluşturmuştuk. Obje içinde de metodu tetiklemiştik. Ancak istersek Object oluşturup metodu tetiklemeden de istediğimiz bir fonksiyonu çalıştırabiliriz. __construct()

Kod yapımızda gördüğünüz gibi bir Object oluşturduk sadece. Class içinde de metodumuzun ismine bakarsanız merhabaDe() değil, __construct() olmuş (İki tane _ işareti yan yana, arada boşluk olmadan yazılır). PHP derlendiğinde, bu metodun ilk çalıştırılacağı anlaşılır ve hemen tetiklenir. Bu kod çalıştırıldığında, fonksiyon çağırılmadığı halde bize “Merhaba” diyecektir. __destruct() Bunun bir de tersi vardır, o da yıkıcı metottur. O da __destruct() ile tanımlanır. Şimdi şöyle bir kod yazıp neler olduğunu inceleyelim…

Bu kod yapımızda, sadece bir adet metodu parametreli olarak çağırıyoruz. Yani $selamlamaMesaji diye bir nesne üretip, bunun içindeki isimAl() metoduna Uğur parametresini gönderiyoruz. Ancak nesneyi oluşturduğumuzda hemen __construct() metodu çalışıp “Merhaba ” yazısını ekrana bastı. Biz de o sırada metoda “Uğur” parametresini gönderdik. Metotla işimiz bitmiş olunca, bu sefer kedisi otomatik olarak __destruct() metodunu devreye soktu ve bize “, güle güle…” dedi. Final olarak bize çıkan mesaj “Merhaba Uğur, güle güle…” oldu.

OOP’de Temel Prensipler, Abstract (Soyutlama)

Her OOP destekleyen programlama dillerinde 4 adet temel prensip vardır. Bunlar zaman zaman oldukça önem taşıyan yaklaşımlardır. Bir nesnenin veya bir değişkenin, dış ortamdan erişime kapatılmasıdır. Yani o değişken veya nesnenin, kendi metodu veya sınıfı içinde dış bağlantılardan kopuk olmasıdır. Bu durum, genelde dışarıdan erişimin engellenmesi veya Class ile uygulama geliştiren kişinin ilgilenmemesi gereken, kullanıcının bir değere atama yapmasında kodların çökmesine neden olabilecek kritik hallerde kullanılır. Soyutlamada, bazı erişim metotları vardır. Bunlar; private, public ve protected ve anahtar kelimeleri ile sağlanmaktadır. Erişim metotları hem değişkenler hem de fonksiyonlar için kullanılabilir. • private: Her yerden erişilebilir. • public: Sadece bağlı olduğu Class tarafından erişilebilir. • protected: Bağlı olduğu Class ve bu Class’tan üretilmiş olan alt Class’lardan erişilebilir (Miras alma konusunda göreceksiniz). Sıralamış olduğumuz bu erişim metotlarına göre bir örnek yapıp inceleyelim…

Yazmış olduğumuz kodlar içinde bir adet erişilmez, yani private değişken var. public olanlara değer ataması yaparken, private olana değer ataması yaparsak program hata verecektir.

OOP’de Temel Prensipler, Inheritance (Kalıtım)

Kalıtım, adından da anlaşılacağı üzere bir varlıktan başka bir varlığa kalıtsal özelliklerin aktarılması olarak tanımlanır. Programlama dünyasında da bir Class’a ait özelliklerin, kendisinden türetilmiş bir alt sınıfa aktarılması olaydır. Buradaki amaç; aynı metotlara sahip olan, yani aynı işleri yapan bir üst sınıftan o özellikleri almaktır. Böylece kod tekrarı sorunu ortadan kalkar. Şimdi şöyle bir örnek düşünelim. Yine bizi selamlayacak bir Class tanımlayacağız. Bu Class’ta iki adet parametremiz olacak. İsmimiz ve cinsiyetimiz. Cinsiyetimiz ne olursa olsun bize iki türlü mesaj verecek. Bu mesajlar; “Merhaba Uğur Bey” veya “Merhaba Bahar Hanım” şeklinde olacaktır. Burada “Merhaba” kelimesi ikisinde de ortak kullanılmış. Biz de ana Class’ta “Merhaba” yazısını yazacak olan metodu tanımlayacağız. Cinsiyetimize göre de “Hanım” veya “Bey” mesajlarını yazdıracak olan fonksiyonu tetikleyeceğiz.

OOP’de Temel Prensipler, Interface (Arayüz)

Buradaki arayüz, görsel bir arayüz gibi düşünülmesin. Soyutlama işlemine benzer. Aslında bir Class’a başlanmadan önce zorunlu olarak tanımlanması gereken metotların belirtildiği bir yapıdır. Yani bir Interface içinde tanımlanan metotlar, bu Interface tarafından genişletilen (implements ile yapılır, soyutlamada ise extend ile yapılıyordu.) alt Class’larda mutlaka yazılmalı, yani oluşturulmalıdır. Eğer bu kurala uyulmazsa Fatal Error denen hatayı verir. Sözdizimini incelersek biraz daha iyi anlayabiliriz.

Ek olarak, bir Interface, extend metodu ile başka bir Interface’ye genişletilebilir. Böyle olursa, genişletilen Interface’de yer alan metotlar da zorunlu olarak kullanılmak zorundadır. Aşağıdaki sözdizimini inceleyin…

Şimdi bir örnekle veritabanına bağlantı kurmaya çalışalım… Yapacağımız örnek biraz karışık gelebilir ilk bakışta, ancak iyice inceleyip bol bol pratik yaptığınızda size çok şey katacaktır. Örneğimizde, bir interface tarafından türetilen bir Class olacak. Bu Class’ta da iki adet fonksiyonumuz ve parametre değerleri olacak. Bu Class, veritabanına bağlanıp bize sonucu yazdıracaktır. İlk metod, veritabanı bağlantısını kuracak, ikinci metot ise veritabanını seçip bize veritabanındaki değerleri yazdıracaktır. Yani kodların çalışabilmesi için PHPMyAdmin panelinde veritabanı oluşturmalı, bu veritabanı için kullanıcı yetkilendirmeli ve veritabanında da birkaç sütun ile birkaç satır veri girmeniz gerekiyor (MySQL ve PHPMyAdmin ile daha detaylı bilgi almak için diğer bölümleri inceleyebilirsiniz). İnterface.class.php

Yazdığımız kodları çalıştırdığımızda şöyle bir ekran görüntüsü alırız:

OOP’de Temel Prensipler, Polymorphism (Çok Biçimlilik)

Kalıtım yaklaşımının biraz daha iç içe geçmiş ve karmaşık gibi görünen halidir. Adından da anlaşılacağı üzere, üretilen alt sınıfların başkalaşım geçirerek farklı farklı görevler üstlenmesini saplar. Ana Class’ın özelliklerini almak ve gerektiğinde değiştirebilmek olarak da tanımlanabilir. Şöyle bir örnek düşünelim. Ana Class’ımızın amacı alan hesabı yapmak olsun. Bildiğiniz gibi üçgen, kare, daire gibi bir takım geometrik şekiller vardır. Bunların hepsinin de alan hesabı birbirinden farklı. Ama görüntü itibari ile yaptıkları görev alan bulmak. Az önce bahsetmiş olduğumuz gibi ana sınıftan alınan bir metot, yani fonksiyon, ihtiyaca göre değiştirilebilir. Kare için a*a formülü uygulayabilirken, dikdörtgen için de a*b uygulanacak. Bu mantıkla metodumuzun işlem türünü değiştirebiliriz. Bu örneğimizi bir de HTML5 formu ile birleştirelim…

Kodlarımızı ilk çalıştırdığımızda aşağıdaki gibi bir sayfa görürüz.

Daire için 5 yarıçap değerini verip Hesapla butonuna bastığımızda da aşağıdaki gibi bir sonuç alırız. İç içe Class’larla çalışırken, yani kalıtım uygularken, ana Class’taki metotlara erişmek için parent:: , kendi Class’ı içindeyken bir metota erişmek için de self:: kullanmanız gerektiğini, her yerden erişilebilir bir değişken oluşturmak için de değişkenin başına global yazmayı unutmayın..

--

--

Full-stack Developer [ UI / UX | JAM Stack | ME(A,R,V)N | LAMP ], Author, Pro Gamer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Uğur GELİŞKEN

Full-stack Developer [ UI / UX | JAM Stack | ME(A,R,V)N | LAMP ], Author, Pro Gamer