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.
İnceleyebilmeniz için bir örnek:
https://codepen.io/ebykdrms/pen/LYrWEaY
İleride CodePen'den silme ihtimalime karşı kodları buraya da bırakıyorum:
<div id="steps">
<div class="step" data-step-name="step-1">
<label>
<span>Ad</span>
<input name="name" required />
</label>
<label>
<span>Soyad</span>
<input name="surname" required />
</label>
<label>
<span>E-posta</span>
<input name="email" />
</label>
<label>
<span>Cinsiyet</span>
<select name="gender" required>
<option value="" disabled selected>Seçiniz</option>
<option value="Kadın">Kadın</option>
<option value="Erkek">Erkek</option>
</select>
</label>
<button class="nextStepButton">
Devam
<i class="fa-solid fa-chevron-right"></i>
</button>
</div>
<div class="step" data-step-name="step-2" data-step-by="Erkek">
<h2 class="hello"></h2>
<label>
<span>Yaş</span>
<input name="age" />
</label>
<div class="stepButtons">
<button class="prevStepButton">
<i class="fa-solid fa-chevron-left"></i>
Geri
</button>
<button class="nextStepButton">
Devam
<i class="fa-solid fa-chevron-right"></i>
</button>
</div>
</div>
<div class="step" data-step-name="step-2" data-step-by="Kadın">
<h2 class="hello"></h2>
<label>
<span>Maaş</span>
<input name="salary" />
</label>
<div class="stepButtons">
<button class="prevStepButton">
<i class="fa-solid fa-chevron-left"></i>
Geri
</button>
<button class="nextStepButton">
Devam
<i class="fa-solid fa-chevron-right"></i>
</button>
</div>
</div>
<div class="step" data-step-name="step-3">
<div class="info"></div>
<div class="stepButtons">
<button class="prevStepButton">
<i class="fa-solid fa-chevron-left"></i>
Geri
</button>
<button class="nextStepButton">
Onayla
<i class="fa-solid fa-check"></i>
</button>
</div>
</div>
</div>
.step {
display:flex;
flex-direction:column;
padding:5px;
border:1px solid #ddd;
margin:10px;
max-width:300px;
opacity:0;
pointer-events:none;
transition:opacity .3s ease 0s;
}
.step.active {
pointer-events:auto;
opacity:1;
}
.step h2 {
padding:10px 5px;
font-weight:bold;
border-bottom:1px solid #ddd;
margin-bottom:5px;
}
.step label {
display:flex;
flex-direction:column;
padding:5px;
}
.step label input,
.step label select {
padding:5px;
margin-top:5px;
border:1px solid #ccc;
outline:none;
}
.step label input.required,
.step label select.required {
border-color:red;
}
.step .stepButtons {
display:flex;
flex-direction:row;
}
.step button {
cursor:pointer;
transition:opacity ease .1s;
}
.step button:active {
opacity:0.5;
}
.step .nextStepButton {
padding:10px;
margin:5px;
margin-top:20px;
border:1px solid #000;
background:#000;
color:#fff;
flex:2;
}
.step .prevStepButton {
padding:10px;
margin:5px;
margin-top:20px;
border:1px solid #000;
background:#fff;
color:#000;
flex:1;
}
.step .nextStepButton i,
.step .prevStepButton i {
margin:0 5px;
}
.step .info table {
margin:5px;
border:1px solid #ddd;
border-bottom:none;
width:calc(100% - 10px);
}
.step .info table tr td {
padding:5px;
border-bottom:1px solid #ddd;
}
function doValidation($wrapper) {
const $inputs = $wrapper.find("input[required],select[required]");
let validationStatus = true;
for(let i=0; i < $inputs.length; i++) {
const $input = $inputs.eq(i);
console.log($input.val())
if(!$input.val() || $input.val().trim()=="") {
validationStatus = false;
$input.addClass("required");
$input.one("input change", function() {
$(this).removeClass("required");
});
}
}
return validationStatus;
}
const $stepsWrapper = $("#steps");
const $steps = $stepsWrapper.find(".step").clone();
$(".step").remove();
const stepDatas = {};
const getStep = (stepName, stepBy=null) => {
const stepNameQuery = `[data-step-name="${stepName}"]`;
const stepByQuery = stepBy ? `[data-step-by="${stepBy}"]` : "";
return $steps.filter(stepNameQuery+stepByQuery);
}
const activeStep = ($step) => {
$(".step").removeClass("active").remove();
$stepsWrapper.append($step);
setTimeout(()=>{$step.addClass("active");},10);
}
$(document).on("click", ".step .nextStepButton", function(){
const $currentStep = $(this).closest(".step");
if(!doValidation($currentStep)) return;
const stepName = $currentStep.attr('data-step-name');
const stepBy = $currentStep.attr('data-step-by');
if(stepName=="step-1") {
stepDatas.name = $currentStep.find(`input[name="name"]`).val();
stepDatas.surname = $currentStep.find(`input[name="surname"]`).val();
stepDatas.email = $currentStep.find(`input[name="email"]`).val();
stepDatas.gender = $currentStep.find(`select[name="gender"]`).val();
const $targetStep = getStep("step-2", stepDatas.gender);
$targetStep.find('h2').text(`Merhaba ${stepDatas.name} ${stepDatas.surname} ${stepDatas.gender=="Kadın"?"Hanım":"Bey"}`);
activeStep($targetStep);
return;
}
if(stepName=="step-2") {
if(stepBy=="Kadın") {
stepDatas.salary = $currentStep.find(`input[name="salary"]`).val();
}
else {
stepDatas.age = $currentStep.find(`input[name="age"]`).val();
}
const $targetStep = getStep("step-3");
const name = `${stepDatas.name} ${stepDatas.surname}`;
const email = stepDatas.email;
const gender = stepDatas.gender=="Kadın" ? "Hanım" : "Bey";
const salary = stepDatas.salary ?? "";
const age = stepDatas.age ?? "";
$targetStep.find('.info').html(`
<table>
<tr><td>Üye</td><td>${name} ${gender}</td></tr>
<tr><td>E-posta</td><td>${email}</td></tr>
<tr><td>Maaş</td><td>${salary}</td></tr>
<tr><td>Yaş</td><td>${age}</td></tr>
</table>
`);
activeStep($targetStep);
return;
}
if(stepName=="step-3") {
alert("Tamam");
activeStep(getStep("step-1"));
return;
}
});
$(document).on("click", ".step .prevStepButton", function(){
const $currentStep = $(this).closest(".step");
const stepName = $currentStep.attr('data-step-name');
const stepBy = $currentStep.attr('data-step-by');
if(stepName=="step-2") {
activeStep(getStep("step-1"));
return;
}
if(stepName=="step-3") {
activeStep(getStep("step-2", stepDatas.gender));
return;
}
});
activeStep(getStep("step-1"));
SQL sorgunuzdan DISTINCT
ifadesini kaldırıp deneyebilirsiniz.