18 Kasım 2022

Bıldırki hurmalar: Kod yazarken yorum koymanın önemi

ile hasan

Çalıştığım yer için bir süredir geliştirmekte olduğum yazılımda invitation-link denen bir mekanizma kurdum. Yazılımı kullanacak kişiye bir davetiye linki üretiyorum. O linke tıklayan sisteme girebiliyor.

Bu link aslında bir JWT token. Çok uzun bir link olduğu ve içerisinde bir kaç yerde nokta (.) geçtiği için Whatsapp’dan gönderince insanlar linke tıklayamıyor. Bunu görünce belki bunu bir URL kısaltma servisi ile kısaltırsam daha şık olur diye düşündüm. Bunu in-house olarak proje içerisinde de yapabilirim ama; 1) Token’i ürettiğim yer ile kullandığım yer aynı ortam değil. 2) Tükettiğim yerde MySQL gibi bir veritabanı yok. İki platformun ortak kullandığı bir Redis var. Orayı da iyi kullanmam, boş yere doldurmamam lazım.

İşte bu nedenle geçen senelerde bir hafta sonu projesi olarak geliştirdiğim Gooo.to URL kısaltma servisini kullanayım dedim. API’si de vardı ama onu bir ara iptal etmişim. Meğer CURL desteği de vermişim 🙂 CURL kullanarak basit bir kod yazdım. Artık ürettiğim davetiye linklerini şak diye kısaltabiliyorum.

# link
http://127.0.0.1:8000/inv/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiSGFzYW4gQ2l2ZWxlayIsImVtYWlsIjoiaGFzYW5jaXZlbGVra29kdmVudHVyZXRla25vbG9qaWhlYmVsZWd1YmVsZXJAZ21haWwuY29tIiwiZXhwb3J0X3V1aWQiOiJlLTRkNzUzZjhlLWQyMWUtNGRmNS1iY2QwLTRlZjAwYzgwZTAzYSIsImlhZCI6MTY2ODc5MjA5OCwiZXhwIjoxNjY4Nzk1Njk4fQ.-hzd77y9gCryKj_0EWliRc2padSH8ScOYryvnDCeFNs
# kısa hali
https://gooo.to/PhQiqD

Fakat daha ikinci denememde (çok şükür) bir sorunla karşılaştım:

Wrong number of segments

Eyvah dedim. Herhalde link çok uzun geldi ve Gooo.to linkin tamamını saklayamadı. Kontrol ettim, text alanı olarak ayırmışım. Gayet uzun metinleri bile saklayabiliyorum. Sonra ürettiğim orijinal link ile Gooo.to’nun döndürdüğü linki karşılaştırayım dedim.

# Gooo.to'nun döndürdüğü link

http://127.0.0.1:8000/inv/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiSGFzYW4gQ2l2ZWxlayIsImVtYWlsIjoiaGFzYW5jaXZlbGVra29kdmVudHVyZXRla25vbG9qaWhlYmVsZWd1YmVsZXJAZ21haWwuY29tIiwiZXhwb3J0X3V1aWQiOiJlLTRkNzUzZjhlLWQyMWUtNGRmNS1iY2QwLTRlZjAwYzgwZTAzYSIsImlhZCI6MTY2ODc5MjA5OCwiZXhwIjoxNjY4Nzk1Njk4fQ.-hzd77y9gCryKj.0EWliRc2padSH8ScOYryvnDCeFNs

Şöyle kabaca bakınca 1. kutu ile bu yukarıdaki 4. kutu aynı gibi duruyor değil mi. Meğer değilmişler. Son satırlara dikkat:

jk4fQ.-hzd77y9gCryKj_0EWliRc2padSH8ScOYryvnDCeFNs
jk4fQ.-hzd77y9gCryKj.0EWliRc2padSH8ScOYryvnDCeFNs

Orijinal linkte alttan tire (_) karakteri Gooo.to’dan dönerken noktaya (.) dönüşmüş. İşte bu bir karakterlik değişim “Wrong number of segments” hatası verdiriyor. Diğer denemelerimde _ içeren bir link oluşmadığından problem olmamıştı. Ama bu linkte iyi ki tesadüfen _ oluşmuş da durumu hemen farkettik.

Hemen GitHub’dan Gooo.to’nun koduna baktım. İşte oradaydı:

$req = $request->all();
if(count($req)==1 && isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/curl/", $_SERVER['HTTP_USER_AGENT']))
{
    // parametre key olarak geldiği için
    // PHP bunlari bir değişkene aktarirken sorun yaşamamak adina
    // kendi politikasi gereği . olarak oluşturulmaya çalışılan değişkenleri _ olarak otomatik çeviriyor
    // bu nedenle domain adindaki .'lar _ olarak dönüyor.
    // bir web adresinde _ olmaz diyerekten hepsini .'ya çevirebiliriz.

    $keys = array_keys($req);
    $target = str_replace("_",".",$keys[0]);

    $link = Link::create(['target'=>$target]);

    // ....
}

Yorumların son satırında çok iddiali bir cümle kurmuşum ve tabiri caizse durumu sallamışım. Bir web sitesinde neden _ olmasın canım. Pekala olabilir. Aha oldu işte :)))

Buradaki durumu da aklımda kaldığı kadarıyla anlatayım. Gooo.to bir URL kısaltma servisi olduğu için parametre olarak URL alıyor. Normalde gooo.to?url=https://blabla diye göndersem hiç sıkıntı yok. Fakat CURL’da yazmak bir tık daha kolay olsun diye gooo.to?https://blabla şeklinde ayarladım. Yani ?https://blabla olan kısım aslında KEY oluyor. Karşısında bir şey göndermem gerekmiyor. Bu key’i doğrudan link olarak alıp kullanabiliyorum. İşte PHP kendi iç politikası gereği parametre keyi olarak gönderdiğim kelimenin içerisinde nokta (.) varsa bunu _’ya çeviriyor. Mesela api.key kullansanız PHP bunu api_key olarak algılayacaktır. Gerekçesi de PHP’de değişken adı olarak nokta (.) kullanılmaması. Yani PHP’de $user.name diyemezsiniz. Dolayısı ile dışardan gönderdiğiniz bir değişkenin adı da nokta içeremez.

İşte ben de “PHP’nin alttan tireye çevirdiği karakterlerin hepsini noktaya geri çevireyim, kurtulayım” dedim ama riskli bir adımdı tabi. Benim örneğimde başıma geldiği gibi kendiliğinden alttan tire olan karakteri de noktaya çevirince işler patladı.

Çözümü zor değil. URL’i parametre olarak ?url=https://blabla şekline dönüştürdüğümde mesele kalmayacak.

Bana da güzel bir ders oldu 🙂