Aşağıdaki kodu https://onlinephp.io sitesinde PHP sürümünü 5.6.40'a çekerek denediğimde sorunsuz çalışıyor.
<?php
date_default_timezone_set("Europe/Istanbul");
$array = "1234|4756|1|31.01.2023,5678|6453|2|01.02.2021,5678|6453|2|01.02.2022";
$fixedArray = [];
$groups = explode(",", $array);
// input ($array): "1234|4756|1|31.01.2023,5678|6453|2|01.02.2021"
// output ($groups): ["1234|4756|1|31.01.2023", "5678|6453|2|01.02.2021"]
foreach($groups as $group) $fixedArray[] = explode("|", $group);
// input ($groups): ["1234|4756|1|31.01.2023", "5678|6453|2|01.02.2023"]
// output ($fixedArray): [["1234", "4756", "1", "31.01.2023"], ["5678", "6453", "2", "01.02.2021"]]
usort($fixedArray, function ($a, $b) {
if(strtotime($a[3]) < strtotime($b[3])) return -1;
if(strtotime($a[3]) > strtotime($b[3])) return 1;
return 0;
});
// input ($fixedArray): [["1234", "4756", "1", "31.01.2023"], ["5678", "6453", "2", "01.02.2021"]]
// output ($fixedArray): [["5678", "6453", "2", "01.02.2021"], ["1234", "4756", "1", "31.01.2023"]]
print_r($fixedArray);
Eğer hem hata vermiyor hem de sıralama yapmıyorsa muhtemelen ekrana doğru değişkeni basmıyorsunuz veya yanlış zamanda basıyorsunuz veya tarihler karşılaştırma yaptığınız index'te (3.index) bulunmuyor. Kodlarınızı görmeden bu aşamadan sonra yanıt vermem zor.
Belki sorun date'tedir diyerek farklı bi'şey deneyebiliriz. date yerine doğrudan string üzerinde de tarih sıralaması yapabiliriz.
Eğer tarihi yıl-ay-gün şeklinde yyyy.mm.dd formatında bir string'e çevirirsek ve alfabetik olarak sıralamaya çalışırsak yine doğru tarih sıralamasına ulaşabiliriz.
Bunu da şu şekilde yapmak mümkün:
usort($fixedArray, function ($a, $b) {
$date1 = explode(".", $a[3]); // "01.02.2022" -> ["01", "02", "2022"]
$date1 = array_reverse($date1); // ["01", "02", "2022"] -> ["2022", "02", "01"]
$date1 = implode(".", $date1); // ["2022", "02", "01"] -> "2022.02.01"
$date2 = implode(".", array_reverse(explode(".", $b[3]))); // Üsttekinin tek satır hali
return strcmp($date1, $date2); // strcmp() fonksiyonu string ifadeleri karşılaştırır. Tam sort'un istediği şekilde -1, 0 veya 1 döner.
});
Bu kodları da aynı sitede denedim ve doğru şekilde tarihleri eskiden yeniye doğru sıralandı.
kullanıcı adres seçince devam et gübi bir butonu aktif etmekten bahsediyorsun sanırım.
diyorsun ki: kullanıcı kendisi dom'u manipule edip kendisi bir adres eklerse ve o adresi seçerse buton yine aktif olacak. o yüzden adres seçildiğinde adresin varlığını kontrol etmek için sunucuma istek atayım ve dönen sonuca göre butonu aktif edeyim.
doğru anladıysam,
böyle bir isteği atmana gerek yok. kullanıcı senin sunucuya istek atacağın fonksiyonu da manipule edebilir. veya sunucuya istek atmana fırsat vermeden butona kendisi de active class'ı verebilir veya disabled prop'unu false yapabilir. hatta kullanıcının bu işlemi yapması için web sitene girmesine bile gerek yok. sunucuna postman gibi bir program üzerinden doğrudan post isteği de atabilir. yani kötü niyetli kullanıcıyı o aşamada durduramazsın.
o yüzden sunucuya ek yük bibdirmene ve performans kaybı yaşamana gerek yok.
senin yapman gereken sayfada performansa odaklanmak olmalı. kullanıcı devam et butonuna bastıktan sonra sunucuya istek atmalısın. sunucu isteği karşıladığında önce adres seçilmiş mi diye bakar. sonra adresin varlığını kontrol eder. bu aşamalarda sorun varsa sonraki sayfayı göstermeden direkt hata sayfasına redirect edilir veya aynı sayfaya bir hata mesajıyla redirect edilir.
eğer sunucu kontrolünde bir sorun yoksa kullanıcı doğru sayfaya (sonraki aşamaya) benzersiz bir token ile redirect edilir. bu token içinde benzersizliği sağlayan bir şifre haricinde şifrelenmiş halde adres bilgisi de bulunur.
sonraki aşamada da sunucu önce token kontrolü yapar. token doğru değilse bu sayfaya kötü niyetli bir istek atılmış demektir. sunucu sayfayı göstermeden kullanıcıyı direkt hata sayfasına redirect eder. token doğruysa içindeki adres bilgisi okunur. böylece yeni sayfada adres bilgileri için yeniden veritabanına sorgu da atılmamış olur. veritabanına ne kadar az istek atılırsa o kadar iyi...
her bir devam et butonu olan sayfanda bu yöntemle ilerlersen hem front end'de performanstan ödün vermemiş olursun, hem veriyi token'larla taşıdığın için veritabanına yük bindirmemiş olursun, hem de kimse senin şifreleme anahtarını bilemeyeceği için istemediğin bir sayfaya erişemez.
Daha önce yazdığım cevabı düzenledim.
// Giriş verilerimiz:
$array = "1234|4756|1|31.01.2023,5678|6453|2|01.02.2021"
// Düzenlenmiş array'i tutacak değişkenimiz:
$fixedArray = [];
// Önce "," karakterinden gruplara ayırıyoruz:
$groups = explode(",", $array);
// input ($array): "1234|4756|1|31.01.2023,5678|6453|2|01.02.2021"
// output ($groups): ["1234|4756|1|31.01.2023", "5678|6453|2|01.02.2021"]
// Sonra her grubu kendi içinde "|" karakterinden ayırıyoruz:
foreach($groups as $group) $fixedArray[] = explode("|", $group);
// input ($groups): ["1234|4756|1|31.01.2023", "5678|6453|2|01.02.2023"]
// output ($fixedArray): [["1234", "4756", "1", "31.01.2023"], ["5678", "6453", "2", "01.02.2021"]]
// Düzenlenmiş grubumuzu tarihe göre küçükten büyüğe sıralıyoruz:
usort($fixedArray, fn($a, $b) => strtotime($a[3]) <=> strtotime($b[3]));
// input ($fixedArray): [["1234", "4756", "1", "31.01.2023"], ["5678", "6453", "2", "01.02.2021"]]
// output ($fixedArray): [["5678", "6453", "2", "01.02.2021"], ["1234", "4756", "1", "31.01.2023"]]
// Sonuç $fixedArray dizisinde bulunuyor:
print_r($fixedArray);
PHP'nin 7'den eski sürümlere uyumlu olması için usort() fonksiyonu şöyle de olabilir:
usort($fixedArray, function ($a, $b) {
if(strtotime($a[3]) < strtotime($b[3])) return -1;
if(strtotime($a[3]) > strtotime($b[3])) return 1;
return 0;
});
Almak istediğin değerlerin hepsini ayrı ayrı hesaplamalısın.
var ntime = new Date("2023-02-20 00:53:00");
var otime = new Date("2023-02-18 00:40:00");
var dtime = (ntime - otime)/(1000);
const days = Math.floor(dtime / (60*60*24)) + " gün";
const hours = Math.floor((dtime / (60*60)) % 24) + " saat";
const minutes = Math.floor((dtime / 60) % 60) + " dakika";
const seconds = Math.floor(dtime % 60) + " saniye";
const text = [days, hours, minutes, seconds].filter(x=>x.split(" ")[0]!=="0").join(" ");
// Çıktı: "2 gün 13 dakika"
https://www.php.net/manual/tr/function.setrawcookie.php
setrawcookie() işlevi, çerez değerini tarayıcıya gönderirken otomatik olarak URL kodlamasından geçirmemesi dışında setcookie() işleviyle aynıdır.
Yani setcookie()fonksiyonu çerez bilgilerini tarayıcıya gönderirken url encode yapar. setrawcookie() fonksiyonu yapmaz. Aralarındaki tek fark bu.
Yani php.net öyle söylüyor.
Ben kodu https://onlinephp.io/ sitesinde denediğimde hata aldım. Hata dedi ki, setrawcookie()fonksiyonunun 2.parametresinde (cookie değeri verilen parametrede) boşluk, virgül falan kullanamazsın!
Yani setrawcookie() fonksiyonuna değer verilecekse önceden url encoding edilmiş bir değer verilmeli.
https://www.php.net/manual/en/function.str-replace.php
$bodytag = str_replace("%body%", "black", "<body text='%body%'>");
// çıktı: "<body text='black'>"
$vowels = array("a", "e", "i", "o", "u", "A", "E", "I", "O", "U");
$onlyconsonants = str_replace($vowels, "", "Hello World of PHP");
// çıktı: "Hll Wrld f PHP"
$phrase = "You should eat fruits, vegetables, and fiber every day.";
$healthy = array("fruits", "vegetables", "fiber");
$yummy = array("pizza", "beer", "ice cream");
$newphrase = str_replace($healthy, $yummy, $phrase);
// çıktı: "You should eat pizza, beer, and ice cream every day"
Sizin durumunuzda şöyle bir örnek verilebilir:
$cumle = "Merhaba Dünya! Ben uzun bir cümleyim ve üzerimde değişiklik yapılacak.";
$silinecekler = ["uzun", "üzerimde"];
$yeniCumle = str_replace($silinecekler, "", $cumle);
// çıktı: "Merhaba Dünya! Ben bir cümleyim ve değişiklik yapılacak."
const sonuc = firstArray.map(x=>secondArray.map(y=>[x, y])).flat(1);
veya
const sonuc = [];
firstArray.map(x=>{
sonuc.push(...secondArray.map(y=>[x,y]));
});
veya
const sonuc = [];
for(let i=0; i < firstArray.length; i++) {
for(let k=0; k < secondArray.length; k++) {
sonuc.push([firstArray[i], secondArray[k]);
}
}
Bu işlemi birkaç farklı yerde kullanacaksan fonksiyonlaştırmanı öneririm:
const matchSetsOneToOne = (set1, set2) => set1.map(x=>set2.map(y=>[x, y])).flat(1);
// Kullanırken:
const sonuc = matchSetsOneToOne(firstArray, secondArray);
Muhtemelen $E = self::$connection->query($SQL); komutunu verdiğiniz sırada henüz $connection değişkenine değer atanmamış oluyor.
DB::primaryID("test"); satırını çalıştırmadan önce __connect() fonksiyonunu çalıtırmanız gerekiyor.
Siz __construct() fonksiyonuyla $connection değişkeninize değer atıyorsunuz ama primaryID() class'ı statik olarak çağırdığınızda __construct() fonksiyonu çağırılmaz.
Hata aldığınız satırdan bir önceki satırda $connection değerinin null olup olmadığını kontrol etmeli ve buna göre hareket etmelisiniz.
Hata mesajı da bundan bahsediyor: null bir değerden query() diye bir fonksiyon çağırıyorsunuz.
Şu 2 fonksiyon yardımcı olsun:
const convertDate = (str, timezoneDiff) => {
const t = str.split(/[- :]/);
t[1]--;
return new Date(Date.UTC(...t) - 1000 * 60 * 60 * timezoneDiff);
}
const diffDate = (date1, date2) => {
const t = date1-date2;
if(t > 0) return {
days: Math.floor(t / (1000 * 60 * 60 * 24)),
hours: Math.floor((t % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)),
minutes: Math.floor((t % (1000 * 60 * 60)) / (1000 * 60)),
seconds: Math.floor((t % (1000 * 60)) / 1000)
}
return {days:0, hours:0, minutes:0, seconds:0}
}
Şu şekilde kullanalım:
let endDateString = "2022-12-25 15:00:00";
const now = new Date();
const endDate = convertDate(endDateString, 1);
const diff = diffDate(endDate, now);
Buradaki convertDate() fonkisyonunun
ilk parametresi MySQL datetime formatında gelen string türdeki tarih.
ikinci parametreyi de sunucunun saat dilimi olarak 1 gönderdik. (+1 anlamına geliyor)
Fonksiyon, sunucunun saat dilimini 0'a çekiyor ve sonra yerel saat dilimine (Türkiye için +3) göre js date objesi oluşturuyor.
diffDate() fonksiyonuna da
ilk parametrede js date objesi olarak sunucudan gelen tarihi,
ikinci parametre olarak da js date objesi olarak şu anki tarihi verdik.
Fonksiyon değerleri hesaplayıp obje halinde return ediyor.