PHP & MySQL Transaction

Transaction İşlemi

Transaction konusunda en yaygın örnek bankaların havale işlemidir.Parayı gönderen kişinin hesabından tutarı düşen 1. sorgu ve daha sonra paranın yatacağı hesaba tutarı ekleyen 2. sorgu çalışır en basit haliyle düşünürsek.Bu işlemlerin hareketlere kaydedilmesi vs. saymazsak bile.

Her iki sorgunun da güvenle gerçekleştiğinden emin olabilmek için “Transaction” yapısını kullanırız.Transaction, prensip olarak ya bütün işlemleri gerçekleştirir ya da hiçbirini gerçekleştirmez..Şimdi bi senaryo üzerinden bunu görelim..

Örnek

Örneğimizde 1 Tablomuz var ve tablo yapımız hesap — tutar şeklinde

Hesap numaraları ve bunların içerisindeki tutarı tutan sütnumuzu var yapıcağımız işlemde Bir hesaptan diğerine para göndericez..

PHP tarafında mysql bağlantılarınızı vs. yaptığınızı varsayıyorum..

Normal Şartlarda sorgularımız aşağıdaki gibidir..


$tutar = 500;
$a = $db->query("UPDATE  test SET tutar = (tutar-$tutar) WHERE hesap = 123 ")or die($db->error);
$b = $db->query("UPDATE  test SET tutar = (tutar+$tutar) WHERE hesap = 321 ")or die($db->error);

Yukarıdaki sorgularımızda herhangi bir hata yok.. İlk sorguda hesaptan tutarı düşerken 2. sorgudada havale yapılan hesaba ekleyen sorgu çalışıcak.. Ancak Sorgulardan 1. çalışıp 2. sinin çalışmadığı durumlarda birinci kişinin hesabından para silindikten sonra ikinci kişinin hesabına para yatmamışsa, pek de hoş durumlarla karşılaşmazsınız.

İşte burda imdadımıza Transaction yapıları yetişmekte. Şimdi aşağıda Transaction kullanarak aynı işlemi gerçekleştirelim..

// Transaction a başlıyoruz
$db->query("SET AUTOCOMMIT=0");
$db->query("START TRANSACTION");

// sorgularımızı hazırlıyoruz
$a = $db->query("UPDATE  test SET tutar = (tutar-$tutar) WHERE hesap = 123 ")or die($db->error);
$b = $db->query("UPDATE  test SET tutar = (tutar+$tutar) WHERE hesp = 321 ")or die($db->error);

if ($a AND $b) {
	    $db->query("COMMIT");
	    echo "BAŞARILI";

	} else {        
	    $db->query("ROLLBACK");
	    echo "Bir Sorun Oluştu";
	}


PHP içerisinde kullanımı da bu şekilde gerçekleşiyor. Kullandğımız yapıların açıklamalarıda aşağıda yer almakta..

  • START TRANSACTION: İşlemi başlatan cümledir.
  • ROLLBACK: Sorgulardan biri gerçekleşmezse işlemi sağlıklı biçimde geri alır, her tablo işlemden önceki haline geri döner.
  • COMMIT: İşlemi gerçekleştirir.

İyi çalışmalar

Laravel’da Sunucuya Dosya Yükleme

Uzun bi aradan sonra herkese merhabalar arkadaşlar.Bugün Laravel’de sunucuya dosya yüklemeyi görücez.Uzatmadan başlayalım.

İlk başta bir blog kodladığımızı ve blog konusu için resme ihtiyacımız olduğunu düşünelim.bunun için bir Rota bilgisi oluşturuyorum.

App\Http\routes.php dosyasını açalım

Route::get('/konu_ekle','HomeController@konu');
Route::post('/konu_ekle','HomeController@konu_kaydet');

Rotamızı oluşturduktan sonra App\Http\Controller Dizinine gidiyorum ve HomeController’i açıyorum.Ekleme formunun görüntüleneceği HomeController’in konu fonksiyonunu düzenliyoruz.

 function konu(){
 return view('blog.konu_ekle');
}

Resourcez\Views\blog\ klasörüne gidiyoruz ve konu_ekle.blade.php dosyamızı oluşturuyoruz.Formumuz basit bi şekilde tasarlıcam aşağıdaki gibi olsun.

@extends('layouts.app')
@section('content')
 form enctype="multipart/form-data" method="POST" action=""> 
  input type="file"  name="resim" class="form-control">
 

Dikkat etmemiz gereken nokta form enctype=”multipart/form-data” ekliyoruz.Yoksa Dosyayı yükleyemezsiniz.

Daha sonra HomeController@konu_ekle fonksiyonuna gidiyoruz.Normalde POST işlemlerimizi Request ile yapıyorduk.Burdada o şekilde yapıcaz sadece birkaç değişikliğimiz olucak

  if (isset($_FILES["resim"]["name"])) {
                        $dosya  = $request->resim;
                        $kaynak = $_FILES["resim"]["tmp_name"];
                        $dosya  = str_replace(" ", "_", $_FILES["resim"]["name"]);
                        $uzanti = explode(".", $_FILES["resim"]["name"]);
                        $hedef  = "./" . $dosya;
                        if (@$uzanti[1]) {
                            if (!file_exists($hedef)) {
                                $hedef   =  "image/".$dosya;
                                $dosya   = $dosya;
                            }
                            move_uploaded_file($kaynak, $hedef);
                        } else {
                            echo " geçersiz dosya tipi ";
                        }
                    }

PHP de olduğu gibi dosyaları $_FILES ile çekiyoruz.Dikkat etmeniz gereken nokta $_FILES[“buraya formdaki name gelicek”] ben kendi kodlarımda public\image\ klasörüne resmi kaydetmesini istedim kodları çalıştırdığımda resim başarılı bir şekilde yüklenmiş olucak.

PHP 7 ile Gelen Yeni Özellikler

PHP5 versiyonu bildiğiniz üzere ZEND Engine II ( C  ile yazılmış PHP’yi tercüme eden bir motor) altyapısı üzerinde çalışıyordu. PHP7’de PHP#NG (Next Generation) motoru kullanılıyor. PHPNG hem sıfırdan temiz bir şekilde yazılmış, hem de aynı anda işleme ve belleği temiz tutma özelliğine sahip bir hafıza yönetimine sahip. Bu da demek oluyor ki PHP7 çok daha hızlı olacak . Hızlı olmasının yanında daha az server gücü ile daha fazla isteğe cevap veriyor. Zend’in yayınladığı tabloda frameworkler’de de belirgin bir performans yükselişi mevcut.

PHP5 Windows sistemlerde  64bit desteği sunmadığı için biraz performans kaybı oluyordu. Hatta deneysel sayılıyordu. PHP7 tutarlı bir 64bit desteği sağlıyor. Bu sayede Windows Server kullanımı da tercih edilebilecek gibi görünüyor.

İsim: PHP 7 (PHP 6 Değil)

Şu anki PHP sürümü 5.6. Bazı tartışmalardan sonra geliştirme ekibi PHP 6 ismini es geçmeye karar verdi. PHP 6, deneysel bir projeydi, fakat bir türlü üretim aşamasına geçemedi.

Kullanıcıların kafasını karıştırmamak için yeni temel sürüm PHP 7 olarak isimlendirildi.

 Yeni -Muhteşem- Zend Engine

Zend motoru, 1999 yılında yeni PHP 4 sürümünden beri PHP’ye güç veriyor. (Zend’i Zend Framework ile karıştırmayın.) Zend, C’de yazılmış, PHP dilini yorumlayan açık kaynaklı bir uygulama motoru. Mevcut PHP 5.X serileri, ilk motorun daha gelişmiş özelliklerini içinde barındıran, dile genişletilebilir bir nesne modeli ve fark edilebilir ölçüde performans geliştirmeleri sağlayan Zend Engine II’yi kullanıyor.

PHP 7 ile birlikte, uygulama motoru PHP#NG (Next Generation) ismini alıyor.

Hata Yakalama

Bir diğer özellik ise hata yakalama kolaylığı. Yeni Engine Exceptions sayesinde ölümcül ve yakalanabilir ölümcül hataları istisnalar (exceptions) ile değiştirebiliyoruz. İstisna yakalanmazsa ölümcül hata dönmeye devam ediyor. Yeni \EngineException nesneleri \Exception temel sınıfından türetilmediği için geçmiş sistemlere uyumluluk da sağlanmış oluyor. \BaseException adı altında yeni bir paylaşımlı üst sınıf sunuluyor. Hata ayıklama ile ilgili ayrı bir yazı yazmak gerekir ama kısaca bir örnek (php.net’ten);

function add(int $left, int $right) {
 return $left + $right;
}
 
try {
 echo add('left', 'right');
} catch (Exception $e) {
 // Handle or log exception.
}

Spaceship (Uzay Gemisi) Operatörü

İki değeri karşılaştırarak; her iki değer eşitse “0″,  soldaki değer büyükse “1″, sağdaki değer büyükse “-1″ döndürür. Örneğin;

// Tam Sayı echo 1 <=> 1; // 0 echo 1 <=> 2; // -1 echo 2 <=> 1; // 1 // Float echo 1.5 <=> 1.5; // 0 echo 1.5 <=> 2.5; // -1 echo 2.5 <=> 1.5; // 1 // String echo "a" <=> "a"; // 0 echo "a" <=> "b"; // -1 echo "b" <=> "a"; // 1

Null Coalesce Operatörü​

Eğer bir değişkenin içeriği varsa belirtilen değeri almak, yoksa varsayılan bir değer atamak için en kısa şekilde Ternary operatörünü kullanıyorduk.

1
isset($_GET['adsoyad']) ? $_GET['adsoyad'] : ""

PHP 7 ile birlikte gelen Null Coalesce operatörüyle bu dizilimi aşağıdaki şekilde daha kısa ve anlaşılır şekilde yazabiliyoruz. Eğer GET ile gelen değişken NULL değilse içeriği $adsoyad değişkenine ata yoksa $adsoyad değişkenine ‘Hiç Kimse’ değerini ata.

$adsoyad= $_GET['adsoyad'] ?? 'Hiç Kimse';

Anonim Sınıflar

var_dump(new class($i) {
 public function __construct($i) {
 $this->i = $i;
 }
});

Dönüş Tipleri

Fonksiyonlarda parametre ve dönüş tipleri belirtilebilinir. Kullanımız zorunlu olmamakla beraber PHP’nin kod okunabilirliği yönündeki büyük bir eksikliği gidermesi açısından önemli. Örnek olarak;

2
3
function topla(int $sayi1, int $sayi2) : int {
 return $sayi1 + $sayi2;
 }

64-bit Windows Desteği

PHP, doğal olarak Linux ortamını kullanıyor, fakat Windows sistemlerde de çalışabiliyor. 5.X serileri henüz 64 bit integer ya da büyük dosya desteği sunmadığı için x64 mimarileri deneysel kabul edilirdi.

PHP 7, 64 bit integer’lar ve büyük dosyalara destek vererek 64 bit Windows sistemlerde de kararlı olarak çalışacak.

Hız İkiye Katlanıyor

PHPNG’nin öne çıkan özelliği, performansı önemli ölçüde artırması. PHPNG’nin geliştirme ekibi, Zend Engine’i yeniden yapılandırdı, bellek kullanımını optimize etti ve uygulama önceliği yerine çalışma zamanında derlemeye izin veren tam zamanında derlemeyi (just-in-time compilation) ekledi.

PHP ile Tek Satırda Update

Herkese merhabalar.Frameworkler ile çalışırken veritabanına veri eklemenin ve güncellemenin çok kolay olduğunu farkettim.Formların name alanlarını veritabanının sütun isimleriyle aynı yaptığınız zaman tek satrıda insert ve update işlemi yapabiliyoruz.Uzun uzun UPDATE sorguları yazmak hem hataya çok açık hemde uğraşması zor oluyor.Bende framework olmadan bunu yapmamızı sağlayan bi fonksiyon yazdım sizlerlede paylaşmak istedim.

function update($dbh,$table,$updateArray,$where)  {

    $totalKeys = "";
    foreach ($updateArray as $key => $value) {
        $totalKeys .= $key . "=" . ':'.$key .",";
    }
    $totalKeys = substr($totalKeys,0, -1);

    $updateSQL = sprintf("UPDATE  %s  SET %s WHERE %s",$table,$totalKeys,$where);

    try {
        return $dbh->prepare($updateSQL)->execute($updateArray);
    } catch(PDOException $exception) {
        return $exception;
        exit;
    }

}

Örnek Kullanımı

Veritabanınızdaki sütun isimleri ile formlardaki name değerlerini aynı yaptığınz zaman size post arrayı geri dönmekte.Bizde bu post arrayını fonksiyona gönderip update etmesini sağlıyruz.

$stmt = update($dbh,"users",$_POST,"id = :id");

Ben test için postları kontrol etmedim ancak siz mutlaka kontrol edin… İyi çalışmalar

PHP Tek Satırda Veritabanına Kayıt Ekleme

Herkese merhabalar.Frameworkler ile çalışırken veritabaına veri eklemek çok kolay olduğunu farkettim.Formların name ilerini veritabanının sütun isimleriyle aynı yaptığınız zaman tek satrıda insert işlemi yapabiliyoruz.Uzun uzun INSERT INTOlarla VALUES larla vs. uğraşmadan bende framework olmadanda bunu yapmamızı sağlayan bi fonksiyon yazdım sizlerlede paylaşmak istedim.

	public function insert($table, $dataArray) 
		{
			$toplamAlan = "";
			$toplamVeri = "";
			foreach ($dataArray as $anahtar => $deger) { //anahtar değerler
				$toplamAlan .= $anahtar . ",";
			}
			foreach ($dataArray as $anahtar => $deger) { // anahtara ait veriler	
				$toplamVeri .= '"'.$deger .'",';
			}
			$toplamAlan = substr($toplamAlan,0,strlen($toplamAlan)-1);
			$toplamVeri = substr($toplamVeri,0,strlen($toplamVeri)-1);

		    $insertSQL = sprintf("INSERT INTO %s (%s) VALUES (%s)",$table,$toplamAlan,$toplamVeri);;
		   	return $this->db->query($insertSQL);
		   
		}

Kullanımı için dediğim gibi veritabanındaki sütunlarla <input ların name= değerleri aynı olması gerekmekte.Örnek kullanım.

 $insert = $db->insert("uyeler",$_POST);

Deneme olduğu için postları ben filtreden geçirmedim.Ancak siz geçirdikten sonra bu şekilde verilerinizi veritabanınıza ekleyebilirsiniz.

Hosting’e Laravel Kurulumu

Merhabalar Arkadaşlar

Öncelikle kendimin karşılaştığı bi problemi sizlerle paylaşıyorum.Laravel ile projeyi geliştridiniz ancak bunu sunucuya attığınız zaman bir takım problemlerle karşılaşıyorsunuz.Bu içerikte bu sorun için .htaccess dosyası paylaşıcam.

Bildiğiniz gibi Laravel default olarak /pulic dizininde çalışmakta.Bu her nekadar güvenlik için güzel bir çözüm olsada kendi sunucusu olmayan paylaşımlı hostinglerde laravel kullanımını zorlaştırmaktadır.Bu konu .htaccess ile aşılabilmektedir.

İlk önce elinizdeki projeyi değişiklik yapmadan sunucunuza atın.Aktarma bittiği zaman siteniz aşağıdaki şekilde olucak

www.site.com

da laravel dosyaları gözükücek.vendors,app, .env gibi yerlere klasör ile erişim var

www.site.com/public

te ise projeniz çalışmakta.Aşağıdaki kodlar ile bir htaccess dosyası oluşturup ana dizine attığınız takdirde bu sorun düzelicektir.

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{REQUEST_URI} !^public
    RewriteRule ^(.*)$ public/$1 [L]
</IfModule>

Oluşturduğunuz htaccess dosyasını ana dizine atın.

Şuanda site.com adresine girdiğiniz zaman direk olarak projenizi görüceksiniz.