PHP 7 ile Gelen Return Type Declarations

Ekim 2015’te stabil olarak yayınlanması beklenen PHP 7’nin code base’ine return type declarations (geri dönüş bildirimi) merge edildi.

Fonksiyonların yorum satırlarına @return int, @return void yazarak o fonksiyonun hangi tipte veri döndürdüğü belirtilirdi. Ancak bunlar birer yorum satırı olduğu için @return array yazan bir fonksiyondan string dönebiliyordu.

Artık PHP 7 ile doğrudan bir fonksiyonun ne tip veri döndürdüğünü dilin kendisinin de anlayabileceği şekilde belirtebiliyoruz.

Hızlıca bir örnek vermek gerekirse:

function getCity(): string {
    return "Ankara";
}

Örnekte olduğu gibi fonksiyon isminden sonra dönecek olan tipi belirtiyoruz.

Peki bu fonksiyonu şöyle değiştirsek:

function getCity(): string {
    return 06;
}

String döneceğini belirttiğimiz fonksiyon integer bir değer döndürdü.

Sizce bu şekilde çalışacak mı?

İlginç gelebilir ancak çalışacaktır. Çünkü PHP 7 ile artık hayatımıza “weak mode” ve “strict mode” kavramları giriyor.

Tahmin edeceğiniz gibi weak mode bu tarz işlere izin veriyor. Strict mode ise kesinlikle belirtilen kurallara uyulmalı diyor.

Strict mode’u nasıl aktifleştireceğiz?

Kodunuzun <?php satırından hemen sonra

declare(strict_types=1);

yazmanız yeterli. Bu satırı eklemezseniz kodlarınız weak mode’da çalışacaktır.

Şimdi kodu şu şekilde düzenleyip çalıştırmayı deneyelim:

declare(strict_types=1);

function getCity(): string {
    return 06;
}

echo "Merhaba";

Uppss… E yine çalıştı? Yani ekrana Merhaba yazıldı. Ama kodun içinde yerinde bulunan fonksiyon string dönmesi gerekirken integer dönüyor hem de strict mode’dayken!

Neden böyle oldu?

Çünkü getCity() fonksiyonundan dönen değeri henüz bir yerde kullanmadık. Bir başka deyişle getCity() fonksiyonunu henüz çağırmadık.

Yani kodu şöyle düzeltirsek:

declare(strict_types=1);

function getCity(): string {
    return 06;
}

echo "Merhaba";

getCity();

Böyle bir hata alacaksınız:

Fatal error: Return value of getCity() must be of the type string, integer returned in test.php on line 6 in test.php on line 6

Bir Sınıfı Return Type Olarak Belirtmek


declare(strict_types=1);

class Car {
    public $type = "Manual";
}

class Mercedes extends Car {

    public $model = "CLA200";
    public $color = "White";
    public $type = "Automatic";

}

class Property {

    public function getCarDetails(): Car {
        return new Mercedes();
    }

}

$property = new Property();
echo $property->getCarDetails()->type;

getCarDetails() metotunda Car sınıfından bir şey döneceğini belirttik. Mercedes sınıfı da Car sınıfından extend edildiği için çalıştı. Aynı şekilde bir interface‘i de return type olarak belirtebilirsiniz.

Null Bir Şeyler Return Edebiliyor Muyuz?

function getCity(): string {
    return null;
}

getCity();

Bu kodu çalıştırdığınızda şöyle bir hata alacaksınız:

Fatal error: Return value of getCity() must be of the type string, null returned in test.php on line 6 in test.php on line 6

Dikkat ederseniz bu kod strict mode’da dahi değil.

Yapıcı ve Yıkıcı Metotlarda Return Type

__construct, __destruct ve __clone metotlarında return type belirtilemiyor.

Void Return Type Nerelerde?

Void return type henüz yok. Gelişimini şuradan takip edebilirsiniz: https://wiki.php.net/rfc/void_return_type

Not: Yazının başında da belirttiğim gibi PHP 7’nin Ekim 2015’te stabil olması bekleniyor. O zamana kadar return type işlerinde yeni şeyler olabilir (void type gelmesi gibi). Eğer yeni bir şey olursa eklemeye çalışacağım.

5 Nisan 2015

Posted In: Genel, Gezegen, php, php7, return type

Php ldap and Custom CA signed certificates


Have you ever had a problem connecting a secure ldap server using php's ldap functions?

It is probably caused by certificate trust issues and 9 out of 10 times root cause is the custom CA can not be recognized by php interpreter.  And as any self respecting devops engineer would solve it by introducing CA's certificate to the system.

But php is a damned monster the normal way to do this, putting the certificate to cacerts dir never works. Even adding  
TLS_CACERT [full.path.to.ca.cert]
line into ldap.conf won't help you. Of course some lucky ones with special deals with Murphy may not have this issue. But believe me, php.net's documentation comments and the internet are full of unresolved ca issues. And sometimes the solution presented is "recompile php with openssl/gnutls/libressl with this custom conf".

If the hell has not opened doors and the earth is not full with demons this solution can not be accepted. there must be a solution.

And of course there is a simple one. PHP uses openssl and openssl respects some environment variables even if you can not make it respect an ldap.conf file. So adding the following lines to your php app with the corresponding paths to your case will fix the issue:

<?php
   putenv('LDAPTLS_CACERTDIR=/etc/ssl/certs/');
   putenv('LDAPTLS_CACERT=/etc/ssl/certs/myCustomCA.crt');
?>

But sometimes even adding ca cert can not be enough. You may have expired certificates or something. So you may need to scrape away the whole certificate validation process. Adding

<?php
   putenv('LDAPTLS_REQCERT=never');
?>
Line to the beginning of your script would solve this issue. And I strongly advice you against doing this.

But this is a simple work around which would work for small scripts or isolated incidents. If you have an established application and you can not modify it? It's one solution to set this environment variables globally in the php server or you may use php's mostly unknown and discarded gem auto_prepend_file.

Just create a file with only the envirionment variable setting lines and use php.ini to prepend this to all php files.





15 Temmuz 2014

Posted In: 2 cents, ca, certificate, devops, ldap, openssl, php, self signed, SSL, TLS

PHP – Redis ile Pub/Sub İşlemi

Redis, kendi içerisinde pub/sub (publish/subscribe) yapılmasına olanak sağlıyor.

Peki pub/sub pattern nedir?

Pub/sub pattern (desen), mesajlaşma pattern’ı olarak geçer. Temelinde; takip edilen bir olayın, takipçilere duyurulması yatar.

Gerçek hayattan örnek verirsek: Öğretmen publish (pub) görevini üstlenir. Öğrenciler ise subscribe (sub) görevini üstlenir. Öğretmen sınav sonuçlarını panoya asar. Öğrenciler de sınav sonucunu bekledikleri için sürekli gözleri panoda bir haber beklerler.

Öncelikle öğretmen görevini yani pub kısmına gözatalım:

pub.php

$teacher = new Predis\Client(array('host' => '127.0.0.1'));

$teacher->publish('Pano', 'Ali, sinavdan AA aldin.');

Gördüğünüz gibi öğretmen Pano’ya Ali isimli öğrencinin sınav bilgisini girdi. Ali de Pano kanalına (channel) aktif olarak abone.

Ali isimli öğrenci Pano kanalını ise şöyle dinleyebiliyor:

sub.php

ini_set("default_socket_timeout", -1); // Ilgili socket surekli dinleniyor

$client = new Predis\Client(array('host' => '127.0.0.1'));

$redis = new Predis\PubSub\DispatcherLoop($client);

$redis->attachCallback('Pano', 'showResult');

$redis->run();

function showResult($data) {
    static $i = 0;
    echo ++$i . '. ogrencinin sonucu aciklandi: ' . $data . PHP_EOL;
}

Deneme yapabilmek için öncelikle sub.php dosyasını ardından pub.php dosyasını çalıştırın. Böylece ilk önce kullanıcıyı Pano isimli kanala abone ediyorsunuz ve artık Pano’dan gelecek mesaajı ekrana basmaya hazır oluyor. Daha sonra pub.php ile Pano‘ya veri giriyorsunuz.

pub.php dosyasını biraz genişletelim. Öğretmen daha çok sınav sonucu açıklasın.

$teacher = new Predis\Client(array('host' => '127.0.0.1'));

$students = array('Ali', 'Ayse', 'Veli', 'Hasan', 'Fatma', 'Oguz');
$results = array('AA', 'BA', 'DC', 'CC', 'AA', 'BA');

for($i = 0; $i < 6; $i++) {
    $teacher->publish('Pano', $students[$i] . ', sinavdan ' . $results[$i] . ' aldin.');
    sleep(1);
}

Yeni pub.php dosyası ile öğretmen, iki dizideki verileri eşleştirerek birer saniye aralıklarla Pano’ya sınav sonuçlarını koyuyor.

Ayrıca bkz.: Observer Design Pattern

5 Aralık 2013

Posted In: Genel, Gezegen, php, pub/sub, redis

Ubuntu LAMP

Giriş
LAMP, Linux Apache Mysql PHP kısaltması olarak aklımızda kalıyor. Bazı yerlerde P yerine PHP'den başka bir dil gelebilir ama bu yazıda PHP'yi anlatacağız. Günümüzde çoğu Linux dağıtımı temel ayarlarla gelmektedir, ben Ubuntu 10.04 LTS kullanıyorum ve temel Birkaç ayarı burada anlatmaya çalışmayacağım, uzmanlar anlatsın :) Aslında kendime not almak için yazıyorum bu yazıyı ama belki ihtiyacı olan vardır diye blogda yayınlıyorum tutorial kıvamında, yanlışım varsa şimdiden affola, yorumlarla bana düzelttirile!

Apache Web Sunucusu Kurulumu ve Ayarları
Apache günümüzde en yaygın olarak kullanılan web sunucularından birisidir. Bu yüzden apache ile ilgili bir çok doküman bulmak mevcut bu kısımda ayrıntıya girmeden apache kurulumu ve yapılandırılmasından bahsedeceğim. Öncelikle sisteminizde ki paketleri güncelleyin.
apt-get update
apt-get upgrade --show-upgraded
Ubuntu üzerinde apache’yi kurmak için aşağıdaki komutu kullanın. Bu komut apache version 2 serisini bilgisayarınıza kuracaktır.
apt-get install apache2
Bu işlemi tamamladıktan sonra sanal konaklama(Virtual Hosting) ayarlarını yapacağız.

Sanal Konaklamayı Ayarlamak
Öncelikle /etc/apache2/ports.conf dosyamızı kontrol edelim. Ben bu dökümanı hazırlarken içersinde
NameVirtualHost *:80
Listen 80
değerleri yazılmış ve hazır şekildeydi. Burada 80. portu dinlediğimizden ve sunucumuzun tüm ipleri dinlediğiden emin oluyoruz. Ardından açacağımız site için /etc/apache2/sites-available/ dizinine bir dosya oluşturuyoruz. Örnek olarak:
touch siteminadi.com
Bu dosyayı vim ile açıyor ve düzenlemeye başlıyoruz:
VirtualHost *:80>
ServerName www.siteminadi.com
ServerAlias siteminadi.com
DocumentRoot /srv/www/siteminadi.com/dosyalarhangidizindeyse/
ErrorLog /srv/www/siteminadi.com/logs/error.log
CustomLog /srv/www/siteminadi.com/logs/custom.log
/VirtualHost> (VirtualHostların başında < şu işaret var ama burada yazınca blogger sapıtıyor)

ServerAlias kullanıcılarınızın sitenize erişmek için kullandığı adresleri içerir, Log dosyaları sitenizin kayıtlarını tutar, document root sitenizi barındırdığınız dizini adresler, servername hangi barınağın hangi adrese gideceğini belirler. Elbette bunları buraya yazmanız direkt çalışacağı anlamına gelmez, DNS'lerini düzggün bir şekilde sunucunuzun IP'sine yönlendirmeniz gerekir. Bundan böyle sunucunuza bir istek geldiğinde önce izin verilen iplerden birisi olup olmadığına bakılır ardından uygun servername aranmaya başlanır ve bulunduğunda bu documentrootta bulunan içeriğe yönlendirilir. Bu dosyayı oluşturduktan sonra ya da önce belirttiğiniz dizinleri oluşturmanız gerekir, yoksa apache hata verir.

mkdir -p /srv/www/siteminadi.com/dosyalarhangidizindeyse
mkdir /srv/www/siteminadi.com/dosyalarhangidizindeyse/logs

Eğer dosyalar zaten ayarlıysa şu komut ile siteyi aktif hale getirirsiniz
a2ensite siteminadi.com
Bu komutla dosyanız sites-enabled dizine kopyalanır ardından apache'yi restart ederek ya da reload ederek siteyi açarsınız.

/etc/init.d/apache2 restart
/etc/init.d/apache2 reload
Mysql Kurulumu ve Ayarları
Öncelikle şu komutu çalıştırın

apt-get install mysql-server

Kurulum sırasında sizden root şifrenizi ayarlamanız istenir, bir şifre belirleyip not ediniz.
Mysql başlı başına bir konudur ama biz sadece bir veritabanı oluşturacağız şu komutla mysql sistemine giriş yaparsınız

mysql -u root -p

Şifrenizi girmenizi isteyecek root şifrenizi girip giriş yapınız.
Database oluşturmak için aşağıdaki komutu kullanın, sonuna ; işareti koymayı unutmayın, mysql'de komutlar ; işareti ile biter.

create database benimdb;

Database oluştu üzerinde bir kullanıcı oluşturup tüm haklarını bu kullanıcıya vermek için aşağıdaki komutu yazınız kullanıcı adı dbadmin şifre 12345 yaptım, siz daha düzgün bir şey seçersiniz.

grant all on benimdb.* to 'dbadmin' identified by '12345';

Flush komutuyla ayrıcalıkları güncelliyoruz.

flush privileges;

İşimiz bitince çıkış yapıyoruz

quit
PHP Kurulumu ve Ayarları
PHP bir programlama dilidir ve LAMP rehberinde onun kurulumunu anlatacağız. Şu komutla kurulumu yaparsınız.

apt-get install php5 php-pear

İsterseniz şu adresteki ayar dosyasını güncelleyebilirsiniz, başlangıç seviyesi kullanıcılar gerekmedikçe bu dosyayı güncellemek zorunda değildir. Çoğu ayar standart şekilde zaten yapılmıştır. Bir değişiklik yaparsanız Apache'yi restart etmeniz gerekir.

/etc/php5/apache2/php.ini

Mysql desteği için şu paketi kurunuz böylece PHP ile Mysql güzelce anlaşmaya başlar, Apache ise zaten PHP'nin dilinden çok iyi anlar ve kısaca LAMP kısmını geride bırakırız.

apt-get install php5-mysql libapache2-mod-auth-mysql

Grafiksel araçlar, çeşitli ayarlar bunların hepsi sonra yapılabilir ama öncelikli olarak sunucunuz artık bu bileşenlere sahiptir. Ayrıntılar vakit bulursam belki ileride burada yayınlanır. Okuduğunuz için teşekkürler

Kaynakça:

http://httpd.apache.org/docs/2.0/en/vhosts/name-based.html

http://library.linode.com/lamp-guides/ubuntu-10.04-lucid/

https://help.ubuntu.com/community/ApacheMySQLPHP

24 Aralık 2010

Posted In: apache, lamp, linux, MySQL, php, ubuntu

WordPress Büyük Boyutlu Dosya Yükleme Sorunu


Başlık belki yanlış oldu, PHP'de büyük boyutlu dosya yükleme sorunu olarak çevirsem daha doğru olurdu ama sorunu Wordpress kullanırken yaşadığımdan ve büyük ihtimal çoğu yeni kullanıcının aynı dertten muzdarip olduğunu düşündüğümden bu başlığı tercih ettim.

Bugunneizlesem üzerinden video yayınlamaya niyetlendim. Eklediğimiz kısa film tanıtımlarına o filmlerin trailerlarını ya da ilgi çekici bazı sahnelerini eklemek ziyaretçilerimizin hoşuna gidebilirdi. Video yayınlama kısmını Wordpress'in zengin eklenti desteği sayesinde hemencecik çözdük. Bir video dosyası yükleyip seçmek yeterli oluyordu ama bir sorun vardı ki dosya yüklerken maksimum boyut 2MB olarak ayarlanmıştı.

Sorunun Wordpressten kaynaklanmadığı kesin gibi bir şeydi, zaten loglarda zaman zaman php ile ilgili çeşitli uyarılarla karşılaşıyordum ve bende php için maksimum dosya boyutu sınırını nasıl arttırabileceğimi araştırdım ve buldum.

.htaccess dosyanızı açıp şu iki satırı ekleyin:
php_value upload_max_filesize 20M
php_value post_max_size 20M

İlki maksimum dosya yükleme limitini, diğeri ise POST verisinin maksimum boyutudur. Başta php.ini dosyasını değiştirip her sitede bu ayarları kullanmayı düşündüm ama ayrı ayrı standartlar belirlemeyi daha uygun buldum. Umarım yazı işinize yarar, kolay gelsin.

4 Temmuz 2010

Posted In: linux, php, upload_max_filesize, wordpress

WordPress, php-rss reader ve simpleXML üzerine

Şu aralar YDÜ-IBM innovasyon merkeziyle haşır neşir yollarda seyyah misali dolaşıyorken web temelli bir projede içerik yönetim sistemi içine başka bir kaynaktan rss çekip göstermek gerekti, php5 ile birlikte gelen aşağıda bir örneğini gördüğünüz simpleXML’i kullanayım dedim.

1
2
3
4
5
6
7
<?php
$rss =  simplexml_load_file('http://erdinc.neu.edu.tr/?feed=rss2&cat=8');
$title =  $rss->channel->title;
foreach ($rss->channel->item as $item) {
  echo "<a href='" . $item->link . "'>" . $item->title . "</a>";
  echo "<p>" . $item->content . "</p>";}
?>

Buraya kadar her şey normal ancak wordpress “Description” tag’ın da belirli bir karakter sayısından sonra feed içine […] kokuyor. Dönüp wordpress koduna baktıktan sonra bu işi en kısa yoldan aşağıdaki gibi çözebilirim diye düşündüm. Böylelikle simpleXML’de kısıtlama olmayan içeriği çok rahat alabildim.

1
2
3
4
5
6
7
8
9
10
11
--- wp-includes/feed-rss2.php.org   2008-06-10 03:08:48.000000000 +0300
+++ wp-includes/feed-rss2.php       2008-06-10 03:45:25.000000000 +0300
@@ -43,9 +43,9 @@
<?php else : ?>
                <description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
        <?php if ( strlen( $post->post_content ) > 0 ) : ?>
-               <content:encoded><![CDATA[<?php the_content() ?>]]></content:encoded>
+               <content><![CDATA[<?php the_content() ?>]]></content>
        <?php else : ?>
-               <content:encoded><![CDATA[<?php the_excerpt_rss() ?>]]></content:encoded>
+               <content><![CDATA[<?php the_excerpt_rss() ?>]]></content>

Belki bir gün birini işine yarar, şimdilik google’ın tozlu raflarından birine yerleşsin :)

10 Haziran 2008

Posted In: coding, lkd, php, rss, wordpress

Twitter Auto Publish Powered By : XYZScripts.com