PHP ile Bir Dosyanın Karakter Kodlamasını Öğrenmek

Geçenlerde altyazıları yüklerken aklıma takıldı. Bazı altyazılar UTF-8, bazıları ise ISO-8859-9. Bu yüzden yazdığım kodlar birini düzgün gösterirken diğerini göstermiyordu. Bu yüzden dosyanın hangi karakter kodlamasına ait olduğunu öğrenmem gerekiyordu. Ve şöyle bir kod yazdım;

$open = file_get_contents('test.srt');
$enc = mb_detect_encoding($open, mb_list_encodings(), true);

echo $enc; // örnek çıktı: UTF-8 ya da ISO-8859-9

Peki bunu bulmak benim ne işime yaradı? Bu sayede header ile karakter setini belirleyebildim şu şekilde;

if ($enc == "UTF-8") {
    header('Content-type: text/vtt; charset=utf8');
} else {
    header('Content-type: text/vtt; charset=iso-8859-9');
}

Buda karakter problemlerimi çözmüş oldu. Bir gün böyle bir hata ile karşılaşırsanız artık çözümünü biliyorsunuz, kolay gelsin.

PHP cURL ile JSON Data Göndermek

Bazen API’ler sizden json data göndermenizi isteyebiliyor, bu gibi durumda cURL ile post işleminde ufak birkaç eklemek yapmak gerekiyor. İlgili kod parçacağına aşağıdan bakabilirsiniz. Ayrıca post edilen yerde alma yöntemi de biraz farklı, onuda 2. kısımda bulabilirsiniz ????

$data = array("name" => "Tayfun", "age" => "24");                                                                    
$data_string = json_encode($data);                                                                                   
                                                                                                                     
$ch = curl_init('http://localhost/b.php');                                                                      
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");                                                                     
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);                                                                  
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);                                                                      
curl_setopt($ch, CURLOPT_HTTPHEADER, array(                                                                          
    'Content-Type: application/json',                                                                                
    'Content-Length: ' . strlen($data_string))                                                                       
);                                                                                                                   
                                                                                                                     
$result = curl_exec($ch);

echo $result;

isteği yaptığımız b.php’de ise json data’yı $_POST ile almaktan biraz daha farklı alıyoruz. Oda şöyle;

$posts = file_get_contents('php://input');
$jsonData = json_decode($posts, true);
print_r($jsonData);

Kolay gelsin ????

PHP ile Sıfırdan Proje Oluşturmak

Bugün bir seriye başlamaya karar verdim. Aslında ilk bölümü çektiğimde bunun bir seri olmasını beklemiyordum ancak zaten eski PHP derslerim eskidiği için yenisini bunun ile çekebilirim.

İlk ders bir projenin altyapısı nasıl olmalı onunla ilgili. Yaklaşık 1 saatten uzun ve bir çok aksiliklerle dolu videoya aşağıdan ulaşabilirsiniz;

Güncelleme: .htaccess dosyanızda RewriteRule kuralının sonuna [QSA] ekleyin. Aksi taktirde $_GET parametrelerini çalıştıramazsınız. Örnek dosyalarda ben değişikliği yaptım, seviliyorsunuz.

Veritabanı sınıfı: https://github.com/tayfunerbilen/BasicDB
Permalink fonksiyonu: http://www.erbilen.net/php-sef-link-fonksiyonu
BasicDB Kullanımı: https://www.youtube.com/watch?v=RX7YxiMYzfA
Örnek dosyalar: https://yadi.sk/d/tt86xMDcxPYFc

Zincirleme (Chain) Metodu

Bir çoğunuz yazılmış sınıfları incelediğinizde şu şekilde bir yazım tarzıyla karşılaşmış olabilirsiniz.

$text = new Text();
echo $text->write('Tayfun Erbilen')->color('red')->fontSize('20px')->show();

Bu örneğe ait sınıfımızı oluşturalım hemen.

class Text {
    
    private $text;
    private $style;

    public function write($text)
    {
        $this->text = $text;
    }

    public function color($color)
    {
        $this->style .= 'color: ' . $color . ';';
    }

    public function fontSize($size)
    {
        $this->style .= 'font-size: ' . $size . ';';
    }

    public function show()
    {
        return '<div style="' . $this->style . '">' . $this->text . '</div>';
    }

}

Ancak bu örnek hata verecektir. Çünkü bu şekilde bir yazım tarzı için yapmanız gereken $this objenizi geriye döndürmek. Yani sınıfımızı şu şekilde düzenlersek eğer;

class Text {
    
    private $text;
    private $style;

    public function write($text)
    {
        $this->text = $text;
        return $this;
    }

    public function color($color)
    {
        $this->style .= 'color: ' . $color . ';';
        return $this;
    }

    public function fontSize($size)
    {
        $this->style .= 'font-size: ' . $size . ';';
        return $this;
    }

    public function show()
    {
        return '<div style="' . $this->style . '">' . $this->text . '</div>';
    }

}

Artık bu şekilde bir kullanımı yapmaya hazırız.

Chain (zincirleme) metodu aynı zamanda jQuery içinde aynı mantıkta çalışır. Muhtemelen her dil için bu mantıktadır. Örneğin jQuery’de bir örnek vermem gerekirse, basit bir eklenti hazırlayalım.

$.fn.Text = function(text){
  $(this).html(text);
};

$('body').Text('Tayfun Erbilen').css({
    'color': 'red',
    'font-size': '20px'
  });

Bu şekilde bir zincirleme kullanımda çalışmayacaktır. Çünkü bir this objesi döndürmedik eklentimizde geriye. Eğer geriye this’i döndürürsek geriye kalan jQuery metodlarını da zincirleme olarak kullanabilirsiniz. O halde buna göre düzelttiğimizde son kod parçamız şöyle olacak;

$.fn.Text = function(text){
  $(this).html(text);
  return this;
};

$('body').Text('Tayfun Erbilen').css({
    'color': 'red',
    'font-size': '20px'
  });

PHP timeAgo Fonksiyonu

Daha önce şurada paylaştığım halini unutup yeni halini kullanabilirsiniz ????

<?php

/**
 * @param $date
 * @return mixed
 */
function timeAgo($date)
{
    $timestamp = strtotime($date);
    $currentDate = new DateTime('@' . $timestamp);
    $nowDate = new DateTime('@' . time());
    return $currentDate
        ->diff($nowDate)
        ->format(' %y yıl %m ay %d gün %h saat %i dakika %s saniye önce');
}

$date = '2015-03-12 14:05:14';
echo timeAgo($date);

BasicDB ile Kolay Veritabanı İşlemleri

1 yıl kadar önce size şu dersimde pdo kullanımını anlatmıştım.
Ancak gerek uzman cevap’ta gerekse gelen maillerde pdo kullanımında sıkıntı yaşıyan arkadaşlar olmuş.
Uzun bir süre önce bende kendi işlerimde kullanmak için pdo’ya ait BasicDB adında bir alt sınıf hazırladım.
Bu sayede veritabanı işlemlerimi daha kolay ve anlaşılır yapabiliyorum.
Sizlere de bu videomda bu sınıfın kullanımını örneklerle anlatacağım.

BasicDB Github Sayfası;
https://github.com/tayfunerbilen/BasicDB

Veritabanı Bağlantısı

$db = new BasicDB('host', 'vtadı', 'kadı', 'şifre');

Veri Ekleme Örneği

$query = $db->insert('uyeler')
            ->set(array(
                 'uye_adi' => 'test',
                 'uye_sifre' => 123456,
                 'uye_eposta' => '[email protected]'
            ));
   
if ( $query ){
  echo 'Last Insert Id: '.$db->lastId();
}

Veri Güncelleme Örneği

$query = $db->update('uyeler')
            ->where('uye_id', 2)
            ->set(array(
                 'uye_adi' => 'başka ad'
            ));
   
if ( $query ){
  echo 'uye guncellendi.';
}

Veri Silme Örneği

$query = $db->delete('uyeler')
            ->where('uye_id', 2)
            ->done();
   
if ( $query ){
  echo 'veri silindi.';
}

Veri Listeleme Örneği

// select
$query = $db->from('icerikler')
            ->join('uyeler', '%s.uye_id = %s.icerik_uye_id', 'left')
            ->where('icerik_onay', 1)
            ->or_where('icerik_onay', 2)
            ->orderby('icerik_id', 'desc')
            ->groupby('icerik_uye_id')
            ->limit(0, 10)
            ->all();
   
if ( $query ){
  foreach ( $query as $row ){
    print_r($row);
  }
}

Tekli Veri Listeleme Örneği

$row = $db->from(‘icerikler’) ->where(‘icerik_id’, 5) ->first(); print_r($row);

Sayfalama Örneği

// toplam veri
$totalRecord = $db->from('users')
                  ->select('count(user_id) as total')
                  ->total();

// sayfa başına kaç veri gözükecek?
$pageLimit = 4;

// sayfa parametresi? Örn: index.php?page=2 [page = $pageParam]
$pageParam = 'page';

// limit için start ve limit değerleri hesaplanıyor
$pagination = $db->pagination($totalRecord, $pageLimit, $pageParam);

// normal sorgumuz
$query = $db->from('uyeler')
            ->orderby('uye_id', 'DESC')
            ->limit($pagination['start'], $pagination['limit'])
            ->all();
            
print_r($query);

// sayfalamayı yazdır
echo $db->showPagination('http://localhost/test/?'.$pageParam.'=[page]');

Php ile Önemli Bilgileri Gizlemek

Başlık biraz saçma olmuş olabilir ancak bazı sitelerde örneğin telefon numaramızı eklediğimizde ilk 2 harf ve son 2 harf gözükür. Geri kalan yerler *** şeklinde filtrelenir.

Bugün uzman cevap’ta böyle bir soru sorulduğu için bir fonksiyon hazırladım, sizlerle de paylaşıyorum. Daha kısa bir yolu var mıdır emin değilim ????

function private_str($str, $start, $end){
   $after = mb_substr($str, 0, $start, 'utf8');
   $repeat = str_repeat('*', $end);
   $before = mb_substr($str, ($start + $end), strlen($str), 'utf8');
   return $after.$repeat.$before;
}

kullanımı ise şöyle;

/* yukarıdaki fonksiyon kodları burada olacak */
$telefon = '05417495744';
echo private_str($telefon, 3, 5); // Çıktı: 054*****744

benzer başka bir örnek ise t.c. kimlik numarasından verelim.

/* yukarıdaki fonksiyon kodları burada olacak */
$tc = '45252204745';
echo private_str($tc, 2, 7); // Çıktı: 45*******45

Böylece betiklerinizde kullanıcıya özel kısımların sadece bir bölümünü göstererek önemli bilgileri başkalarından gizlemiş olursunuz.

Not: Örnekteki T.C. Numarası sallamadır.

HTML Kodlarını Şifrelemek

Bazen front-end işlerde kullanıcıya demo gösterirken kaynak html’i şifrelemek istiyorum.
Her ne kadar işi bilen birisi yine çalacak olsa çalabilir ancak yine de güzel bir önlem olabilir.
Bunun için javascript ile örneklerini inceledim ve php’de aynı olayı hazırladım.
Sizde bu örneği kullanarak html çıktınızı şifreleyebilirsiniz.

Örnek bir kullanım;

<?php

require 'HTML_Encrypt.php';

$html = '<!doctype html>
<html>
<head>
  <meta charset="utf8">
  <title>Example</title>
</head>
<body>

  <h1>Welcome Test Page</h1>

</body>
</html>';

print HTML_Encrypt::encrypt($html);

/**
  örnek çıktı:
  <script type="text/javascript">document.write(unescape("%3c%21%64%6f%63%74%79%70%65%20%68%74%6d%6c%3e%20%20%3c%68%74%6d%6c%3e%20%20%3c%68%65%61%64%3e%20%20%20%20%3c%6d%65%74%61%20%63%68%61%72%73%65%74%3d%22%75%74%66%38%22%3e%20%20%20%20%3c%74%69%74%6c%65%3e%45%78%61%6d%70%6c%65%3c%2f%74%69%74%6c%65%3e%20%20%3c%2f%68%65%61%64%3e%20%20%3c%62%6f%64%79%3e%20%20%20%20%20%20%3c%68%31%3e%57%65%6c%63%6f%6d%65%20%54%65%73%74%20%50%61%67%65%3c%2f%68%31%3e%20%20%20%20%3c%2f%62%6f%64%79%3e%20%20%3c%2f%68%74%6d%6c%3e"));</script>
**/

?>

Sınıfı indirin;

https://github.com/tayfunerbilen/HTML_Encrypt

(alt + n) ile oluşturulan özel karakterleri engellemek (php)

Örnek vermek gerekirse.. Boşluk kontrolünde trim’den geçen alt + 255 ile oluşturulmuş boşluk karakterine bir gün denk geleceksiniz. Bu yüzden yaptığınız kontroller bir işe yaramamaya başlayacak ve boş içerikler gönderecek kötü niyetli insanlar. Bunu önlemek için bu gibi özel karakterleri bir fonksiyon yardımı ile süzmemiz gerekiyor.

function alt_replace($string){
	$search = array(
		chr(0xC2) . chr(0xA0), // c2a0; Alt+255; Alt+0160; Alt+511; Alt+99999999;
		chr(0xC2) . chr(0x90), // c290; Alt+0144
		chr(0xC2) . chr(0x9D), // cd9d; Alt+0157
		chr(0xC2) . chr(0x81), // c281; Alt+0129
		chr(0xC2) . chr(0x8D), // c28d; Alt+0141
		chr(0xC2) . chr(0x8F), // c28f; Alt+0143
		chr(0xC2) . chr(0xAD), // cdad; Alt+0173
		chr(0xAD)
	);
	$string = str_replace($search, '', $string);
	return trim($string);
}

Evet artık post ya da get değerlerini alırken şöyle kullanırsak;

alt_replace($_POST['test']);
alt_replace($_GET['test']);

bu gibi sorunlarla karşılaşmamış oluruz.

kolay gelsin.

“Cannot modify header information – headers already sent by” hatası ve çözümü

Dün yine aynı sorun başıma gelince biraz araştırma yaptım ve olası tüm hataları ve çözümlerini öğrendim.
Buna istinaden bir makale hazırlamam gerektiğine karar verdim ???? Öncelikle bu sorun bütün hostlarda karşılaşılmayan bir sorun. Bazı ayarların farklı olmasından kaynaklanıyor ve dolayısı ile heran başınıza gelebilecek bir sorun.

Çözüm Yolları

1- Tüm kodların en üstüne ob_start() koymak.

<?php

ob_start();

echo 'test..';

header('Location:http://www.erbilen.net');

?>

2- Sorun devam ediyorsa bu yüksek ihtimalle çalıştığınız dosyanın formatının utf-8 bomsuz olmayışından kaynaklıdır. Hemen notepad++ yardımı ile sayfanızın açın ve sayfa kodlamasını utf-8 bomsuz olarak değiştirin.

Birkaç çözüm yolu daha var ama ben onların işe yaradığını sanmıyorum. Beni 2. yöntem kurtardı. Zaten ob_start() kullanıyordum meğerse sayfam utf8 miş ama bomsuz olmadığı için sorun çıkarıyormuş. Bilginize.