Bir kez daha bakınca aslında daha kısa SQL oluşmasını sağlayabilirmişiz gibi göründü.
Mesela ilk foreach döngüsünde oluşturup $whereCondition değişkenine atadığımız string örnek olarak şöyle:
(orderId='123' auth='abc') OR (orderId='131' auth='abc') OR (orderId='213' auth='abc')
yani aslında auth sütunu hep aynı. O halde bunu tek bir AND ifadesiyle birleştirebilirdik. Yani:
auth='abc' AND (orderId='123' OR orderId='131' OR orderId='213')
şeklinde yazabilirdik. Muhtemelen az da olsa MySQL için de daha rahat bir sorgu olacaktır. İki sütunu her OR bloğu için kontrol etmemiş olur.
Bu durumda aşağıdaki şu satırları:
foreach ($detail as $keys) {
$whereConditions[] = "(orderId='" . $keys["orderId"] . "' AND auth='" . $this->appkey . "')";
$whereConditionsWithESD[] = "(ESD.orderId='" . $keys["orderId"] . "' AND ESD.auth='" . $this->appkey . "')";
}
$whereCondition = implode(" OR ", $whereConditions);
$whereConditionWithESD = implode(" OR ", $whereConditionsWithESD);
şu şekilde değiştirmek daha yerinde olur:
foreach ($detail as $keys) {
$orderId = $keys["orderId"];
$whereConditions[] = "orderId='$orderId'";
$whereConditionsWithESD[] = "ESD.orderId='$orderId'";
}
$whereCondition = implode(" OR ", $whereConditions);
$whereConditionWithESD = implode(" OR ", $whereConditionsWithESD);
$appKey = $this->appkey;
$whereCondition = "auth='$appKey' AND ($whereCondition)";
$whereConditionWithESD = "ESD.auth='$appKey' AND ($whereCondition)";
Böylece satır sayısı biraz arttı ama MySQL için daha rahat bir sorgu oluşturduk.
Aşağıdaki satırlarda sanırım $orderList objesindeki değer kodunuzdaki diğer kurgularla uyuşmadığı için yeni bir formata çevirerek orderId değerlerine göre gruplamışsınız.
O kısmı şu şekilde değiştirirseniz daha kısa kodla işi çözebilirsiniz sanıyorum.
Yani yukarıdaki kodlardan sonra gelen kodlarınızdaki $orderListESD = []; ile başlayıp $orderList = $orderListESD; ile biten kısmı komple silip yerine şunu yazabilirsiniz:
$relationalOrderList = [];
foreach($orderList["detail"] as $detail) {
$orderId = $detail["orderId"];
$relationalOrderList[] = [
"detail" => $detail,
"address" => array_filter($orderList["address"], function($item){ return $item["orderId"]===$orderId; }),
"cargoDetail" => array_filter($orderList["cargoDetail"], function($item){ return $item["orderId"]===$orderId; }),
"customerDetail" => array_filter($orderList["customerDetail"], function($item){ return $item["orderId"]===$orderId; }),
"list" => array_filter($orderList["list"], function($item){ return $item["orderId"]===$orderId; }),
];
}
$orderList = $relationalOrderList;
<div>
<input type="hidden" name="content_id" value="123">
<input type="text" name="content_detail" class="form-control" value="abc1">
</div>
<div>
<input type="hidden" name="content_id" value="132">
<input type="text" name="content_detail" class="form-control" value="abc2">
</div>
<div>
<input type="hidden" name="content_id" value="213">
<input type="text" name="content_detail" class="form-control" value="abc3">
</div>
<div>
<input type="hidden" name="content_id" value="231">
<input type="text" name="content_detail" class="form-control" value="abc4">
</div>
Bu şekilde input'lar var ve data key'iyle post ediliyorlar.
content_id ve content_detail dizi olarak PHP'ye iletiliyor ve bu dizilerin eleman sayıları aynı.
HTML'de de doğru sıralamayla dizilmişlerse yukarıdaki html koduna benzer yapıdan giden POST isteğinin PHP'de şu şekilde bir karşılığı oluşuyor olmalı:
$_POST["data"]["content_id"] = ["123", "132", "213", "231"];
$_POST["data"]["content_detail"] = ["abc1", "abc2", "abc3", "abc4"];
Bunları tek bir çatı altında birleştirmek istiyorsanız:
$content = [];
$contentCount = count($_POST["data"]["content_id"]);
for($i=0; $i < $contentCount; $i++) {
$content[] = [
"id" => $_POST["data"]["content_id"][$i],
"detail" => $_POST["data"]["content_detail"][$i]
];
}
echo "<pre>";
print_r($content);
echo "</pre>";
Böylece $content değişkeninde verileri toplamış oldunuz.
Video'yu izlemedim ama cevap gelmediği için şöyle bir yorum yapayım...
Promise kullanmasaydı ve request() fonksiyonunu async key'i ile tanımlasaydı da aynı işlemi yapabilirdi.
Promise kullanarak hangi durumda then() veya hangi durumda catch() bloğuna düşeceğini resolve() ve reject() fonksiyonlarıyla belirleyebildi.
request(url,data)
.then(result=>{
/* resolve() ile gönderilen result değeri buraya geldi */
})
.catch(result=>{
/* reject() ile gönderilen result değeri buraya geldi */
});
Peki aynı fonksiyonu Promise olmadan yazsaydı?
function async request(url, data = false, method = 'GET') {
const options = {
method
}
if (data && method === 'POST') {
options.body = JSON.stringify(data)
}
const response = await fetch(url, options)
const result = await response.json();
if (response.ok && response.status === 200) {
return result;
} else {
throw result;
}
}
Böyle yazsaydık request() fonksiyonunu şöyle kullanacaktık:
request(url,data)
.then(result=>{
/* return ile gönderilen result değeri buraya geldi */
})
.catch(result=>{
/* throw ile gönderilen result değeri buraya geldi */
});
Evet, Promise kullanmasa da olurmuş. :))
Belki fonksiyonu geliştirmeyi, anlamsal olarak ayrıştırmayı veya paralel istekler atabilme ihtimalini düşünmüştür ama sonra gerek kalmamıştır.
Mesela request() fonksiyonunun paralel çalışacak 2 işlem yürütmesi gerekiyor ama bunların sadece birinin sonucunu alacak diyelim.
function request(url, data = false, method = 'GET') {
new Promise(async(resolve, reject) => {
setTimeout(()=>{ console.log("Ben de çalıştım!"); }, 4000);
});
return new Promise(async (resolve, reject) => {
const options = {
method
}
if (data && method === 'POST') {
options.body = JSON.stringify(data)
}
const response = await fetch(url, options)
const result = await response.json();
if (response.ok && response.status === 200) {
resolve(result)
} else {
reject(result)
}
})
}
Böylece request() fonksiyonu çalıştığı anda ilk promise devreye girdi. Beklemeden 2.promise'ı return etti.
Tek fonksiyonda paralel iki işlem yürütmüş oldu. İlk promise 4 saniye sonra işlemini tamamlayacak. Ama request() fonksiyonu mutlaka 2. promise'ın tamamlandığı zaman sonuç döndürecek.
Belki de sadece anlamsal olarak Promise kullanmak istemiş olabilir.
Yani request() fonksiyonuna baktığı zaman burada asenkron bir işlem olduğunu anlamak Promise adını görünce onun için daha hızlı şekilde anlaşılır oluyordur.
<div class="card">
<div class="imageSide">
<img src="https://picsum.photos/100" />
</div>
<div class="informationSide">
<div class="information">
<strong>120.235</strong>
<span>TAKİPÇİLER</span>
</div>
<div class="information">
<strong>120.235</strong>
<span>TAKİP EDİLEN</span>
</div>
</div>
</div>
.card, .card * {
display:flex;
margin:0;
padding:0;
flex-direction:column;
}
.card {
width:350px;
border:1px solid gray;
border-radius:10px;
background:#09c;
flex-direction:row;
align-items:center;
justify-content:space-between;
}
.card > .imageSide {
}
.card > .imageSide > img {
border-radius:50%;
width:100px;
margin:15px;
}
.card > .informationSide {
flex-direction:row;
flex-wrap: wrap;
align-items:center;
justify-content:flex-end;
margin-left:auto;
}
.card > .informationSide > .information {
width:100px;
text-align:center;
padding:5px 15px;
}
.card > .informationSide > .information > strong {
font-size:22px;
}
.card > .informationSide > .information > span {
font-size:12px;
}
.card elementinin width değerini artırdığınızda, takip elementlerinin yan yana geldiğini görebilirsiniz.
Bunu sağlayan flex tasarımda kullanılan flex-wrap özelliğidir.
foreach içinde sql sorgusu atmamalısınız.
Hepsinde ortak olan sanırım orderId ve auth sütunları.
İlk sorgunuzdan sonra bu orderId ve auth değerlerini bir string içinde birleştirin ve or'larla birbirine bağlayın.
$detail = $this->connect->query("...");
$rowPD = $detail->rowCount();
$orderList = [];
$whereConditions = [];
$whereConditionsWithESD = [];
if ($rowPD > 0) {
$detail = $detail->fetchAll(PDO::FETCH_ASSOC);
foreach ($detail as $keys) {
$whereConditions[] = "(orderId='".$keys["orderId"]."' AND auth='".$this->appkey."')";
$whereConditionsWithESD[] = "(ESD.orderId='".$keys["orderId"]."' AND ESD.auth='".$this->appkey."')";
}
$whereCondition = implode(" OR ", $whereConditions);
$whereConditionWithESD = implode(" OR ", $whereConditionsWithESD);
$detail = $this->connect->query("... WHERE $whereCondition")->fetch(PDO::FETCH_ASSOC);
$adress = $this->connect->query("... WHERE $whereCondition")->fetchAll(PDO::FETCH_ASSOC);
$cargoDetail = $this->connect->query("... WHERE $whereCondition")->fetch(PDO::FETCH_ASSOC);
$customerDetail = $this->connect->query("... WHERE $whereCondition")->fetch(PDO::FETCH_ASSOC);
$list = $this->connect->query("... WHERE $whereConditionWithESD ...")->fetchAll(PDO::FETCH_ASSOC);
$orderList = [
"detail" => $detail,
"adress" => $adress,
"cargoDetail" => $cargoDetail,
"customerDetail" => $customerDetail,
"list" => $list
];
}
Sorgularınızın içeriğini bilmiyorum ama hepsinin WHERE koşulu aynı. sadece WHERE koşullarını yukarıdaki gibi düzenleyebilirsiniz.
Örneğin foreach içindeki ilk 4 sorgunuzdaki
where orderId='$orderId' and auth='$this->appkey'
yerine
WHERE $whereCondition yazacaksınız.
$list için olan son sorguda da
WHERE ESD.orderId = '$orderId' AND ESD.auth = '$this->appkey'
yerine
WHERE $whereConditionWithESD yazacaksınız.
Böylece mesela $detail için her foreach döngüsünde
WHERE orderId='123' auth='abc',
WHERE orderId='131' auth='abc',
WHERE orderId='213' auth='abc' şeklinde yazıp istek atmadık da,
tek bir $detail sorgusu için
WHERE (orderId='123' auth='abc') OR (orderId='131' auth='abc') OR (orderId='213' auth='abc')
şeklinde istek attık.
Yani mesela ilk sorgunuzdan 3 tane orderId döndüyse
foreach içindeki 5 sorgunuz 3 defa çalışacak ve MySQL'e 15 defa istek atacaksınız.
Yeni durumdaysa kaç tane orderId olursa olsun MySQL'e sadece 6 istek atacaksınız.
Veritabanına mümkün olduğunca az istek atılmalı. Bu işlem tek başına daha hızlı sonuç almanızı sağlayacaktır.
Eğer $list sorgunuzda olduğu gibi diğer sorguları da tek sorguda birleştirme şansınız varsa çok daha iyi sonuç alırsınız.
MySQL ile mümkün olduğunca az bağlantı kurmalısınız.
NOT: bu işlem sonunca var_dump() ile $orderList değişkeninizi kontrol etmeniz gerekiyor. Çünkü sizin aldığınız json formatıyla bu yeni json formatı artık farklı. Ama her iki durumda da veritabanındaki aynı değerler artık elinizde.
Merhaba @262efe.
Input'tan aldığın değerler varsayılan olarak string türündedir. Input'tan gelen değerin sayı olup olmadığını isNaN() fonksiyonuyla test edebilirsin. Sonra da Number() fonksiyonuyla bu değeri sayıya çevirmelisin. Daha sonra işleme sokabilirsin. Eğer bölme işlemi yapacaksan bölen sayının sıfır olmadığına emin olmalısın çünkü sıfıra bölümler de NaN döner.
Input'tan aldığın verinin bir sayıyla çarpımıyla ilgili örnek:
<input id=userNumber type=number placeholder="Bir sayı girin" />
<button id=calculationButton>Hesapla</button>
<div id=resultArea></div>
// Butonu id attribute'si ile seçiyorum ve $calculationButton adlı değişkene atıyorum.
// Zorunlu değil ama bir elementi değişkene atıyorsak değişken adını $ işaretiyle başlatırız.
const $calculationButton = document.getElementById("calculationButton");
// input elementini de bir değişkene alıyorum.
const $userNumber = document.getElementById("userNumber");
// Sonucu yazacağımız div elementini de bir değişkene alıyorum.
const $resultArea = document.getElementById("resultArea");
// input'a girilen sayıyı hangi sayıyla çarpacağımızı da belirleyelim.
const constantNumber = 2;
// Butonun click olayını dinliyorum.
$calculationButton.addEventListener("click", function() {
// input'taki değeri bir değişkene alıyorum.
// Bu değişkenin değerini daha sonra değiştireceğim için const yerine let kullanarak oluşturuyorum.
let inputValue = $userNumber.value;
// Aldığım değerin sayı olup olmadığını kontrol ediyorum.
// Eğer sayı değilse bir uyarı verip işlem yapılmasını engelliyorum.
if(isNaN(inputValue)) {
$resultArea.innerHTML = "Bir sayı değeri girmelisiniz!"; // div'e uyarı mesajını yazdım.
$userNumber.value = ""; // Input'a yazılan değeri sildim.
return; // Bu fonksiyonun bu adımdan sonra çalışmamasını sağladım.
}
// Input sayısal değer içeren bir string'tir.
// Örneğin "12" bir string'tir ama tamamen sayılardan oluştuğu için
// isNaN() fonksiyonu bunun bir sayı olduğunu söyler. Biz bunu "12" değil 12 yapacağız:
inputValue = Number(inputValue);
// Artık güvenle çarpma işlemimizi yapabiliriz.
// Bölme işlemi yapmayacağımız için sayının 0 olup olmaması önemli değil.
// Sabit sayımız olan constantNumber ile input'un değeri olan inputValue'yi çarpabiliriz.
const result = constantNumber * inputValue;
// Bulduğum değeri resultArea id'li div elementine yazıyorum:
$resultArea.innerHTML = constantNumber + " x " + inputValue + " = " + result;
});
Mobil uygulama geliştirici olmak istiyorsanız, sırayla:
- İngilizce
- Javascript'i ilerletme, ES6, ES7, ES8, ES9, ES10...
- React Native
- TypeScript (ben sevmem)
Web geliştirici olmak istiyorsanız, sırayla:
- Html, css, javascript
- İngilizce
- Javascript'i ilerletme, ES6, ES7, ES8, ES9, ES10, ES11...
- React
- TypeScript
- Next.js
Mobil veya Web aşamalarından sonra sonra
- Express.js ile web servis geliştirme
- MySql veya MongoDb
- Redis
- Docker, Nginx
...
Neden React üzerinden yürüyoruz? Çünkü piyasaya hakim.
Svelte ile ilgili 1 iş, Vue ile ilgili 15 iş, Angular'la 20 iş, React ile ilgili 50 iş bulursunuz.
Mobil tarafta da Flutter ile 10 iş buluyorsanız React Native ile 50 iş bulursunuz.
Oranları uydurdum ama olay tamamen piyasa hakimiyeti. Bu hakimiyet hem Türkiye'de hem yurt dışında böyle. Uzun zaman da bu hakimiyet bozulmayacaktır. Bozulacak olsa Svelte gelir ve hepsini piyasadan silerdi. Deno gelir ve Javascript'i bitirirdi. Node.js gelir Apache'yi bitirirdi ve PHP projesi sonlanırdı. Bitirebildiler mi? Bitiremediler. Kolay kolay da bitiremezler.
Geçmişte piyasaya hakimiyet kurup da bir anda sonlanmış proje hiç yok mu? Var. Ama bu çok çok nadir yaşanan bir durum. Nitekim öldü bitti diye 10 yıldır yaygara koparılan PHP halen çok yaygın şekilde kullanılıyor.
1. Veriyi GET değil POST metoduyla gönderin.
2. Veriyi Cookie'ye kaydedin ve diğer sayfada cookie'den okuyun.
3. Veri sadece front-end'de kullanılacaksa sessionStorage'a kaydedin ve diğer sayfada da sessionStorage'dan okuyun.
4. Veriyi session yoluyla iletin.
5. GET ile gönderdiğiniz parametreleri şifreleyin ve diğer sayfada şifreyi çözün.
6. Verileri veritabanına kaydedin ve diğer sayfada veritabanını kontrol edin.
... aklıma gelenler bunlar.
Ama sizin yapmak istediğiniz şey, bir kullanıcı login olmuşsa bunu session'a kaydetmek ve index.php'de de session'ı kontrol etmek.
B sitesinin veritabanına bağlanma işini doğrudan B sitesinden erişerek yapabilirsiniz.
1. B sitesinde web servis gibi çalışacak bir sayfa oluşturun. Bu sayfa kendisine POST yöntemiyle gelen verileri alsın, kendi veritabanına yazsın.
2. A sitesinden bu B sitesindeki sayfaya POST isteği gönderin.
B sitesinde integration.php sayfası
$productId = $_POST["product_id"];
$newPrice = $_POST["price"];
updateDatabase("UPDATE products SET price='$newPrice' WHERE id=$productId");
echo json_encode(["status"=>true, "message"=>"Price updated successfully"]);
exit();
A sitesinde bir ürünün fiyatını kendi veritabanına kaydederken, B sitesine de durumu bildiren sayfa
// ... A sitesi kendi veritabanında güncelleme işini yaptıktan sonra B sitesine de verileri gönderiyor...
$fields = ['product_id' => '1234', 'price' => '19.90'];
$postvars = http_build_query($fields);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://b.site/integration.php");
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $postvars);
$result = curl_exec($ch);
curl_close($ch);
// Burada da dönen $result değerine göre işlemin başarılı/başarısız oluşuna göre aksiyon alınabilir...
Dikkat: Bu örneklerde hiçbir güvenlik önlemi alınmadığı için saldırıya çok açık.
B sitesinde hangi siteden istek atıldığının tespiti, SQL injection önlemleri, A sitesinin B sitesine istek göndermeden önce B sitesinde oturum açması veya bir token alması...
Ama temel olarak sunucular arası veritabanı bağlantısı kuramıyorsanız siz de böyle bir yola başvurabilirsiniz.
Eğer her component kendi isteğinin verilerini sadece kendisi kullanacaksa istekleri component'lerin kendi içinde tutmanız iyidir.
Eğer bazı istekler birden çok component'i etkilecekse bu yönetimi ana component'te tutmak iyidir.
React, ana component'te herhangi bir state değişimi olduğunda tüm alt component'lerini tekrar kontrol eder ve DOM'da bir değişiklik gerekip gerekmediğine bakar. Eğer gerekmiyosa DOM'u güncellemez. Ama yine de bu kontrolün de bir maliyeti vardır.
Örneğin ana component'inizde 5 tane alt component var. Bu component'lerden hepsi kendi isteğini atıyor ve dönen veriyi kendi içinde işliyor. Ama biri var ki, dönen sonucu işledikten sonra bir de ana component'e veri iletmesi gerekiyor.
İşte bu durumda React ana component'te bir aksiyon gerçekleştiği için 5 component'i birden yeniden taramak zorunda kalıyor ki bu değişikliğin onları etkileyip etkilemediğinden emin olsun...
Bu durumun önüne geçmelisiniz. Kendi yağında kavrulan 4 component'inizin tekrar kontrol edilmemesini sağlamalısınız. Bunun için de bu 4 component'i React.memo() fonksiyonu içine alabilirsiniz.
Böylelikle React bu component'leri, onlara gönderdiği parametrelerde bir değişiklik olmadığı için, yeniden kontrol etmeyecek. Onları sanki pure component gibi varsayıp geçecek.
Ben bu durumda muhtemelen 4 component'i React.memo() korumasına alırdım ama 5.component'in isteğini o component'in içinde değil ana component'te atardım. Sonucu da props yoluyla 5.component'e iletirdim.
Ama tabi hangi yöntemi kullandığınızda daha iyi performans alacağınız sizin kurgunuza bağlı. Belki de tüm istekleri ana component'te atmalı ve sonuçları diğer component'lere prop yoluyla iletmelisinizdir...