v2.5.2
Giriş yap

php dizisini sayfada kullanmak için nasıl saklarım.

kartal
795 defa görüntülendi

Merhaba kimseler görmeden sayfaya getirdiğim php dizim var :)

Şaka bi yana..

Ürün sayfamda ürün ve varyantları var.

Sorgudan gelen varyant bilgilerinin olduğu dizi :
$vary_info; // array

ÜRÜN ADI X

Ürün fiyatı xx

Renk
Siyah - Beyaz

Matterial
Cotton - Keten

Varyant seçtiğimde fiyat ve ürün adınıda varyanta göre değişmesini istiyorum

$vary_info içinde varyant id var ve varyant seçtiğimde seçtirmek için kullanacağım id
hazır oluyor ama sorunum

$vary_info dizisini nerede tutacağım form içinde
araştırmama göre sorgudan gelen diziyi tutamıyorum.

Ajax kullansam kullanıcı sürekli varyantlarla oynadığında sürekli sorgu atılacak

Acaba local storage kullansam sayfa açıldığında varyant bilgilerini saklamak için bunu nasıl yapıyorlar

ebykdrms
698 gün önce

Merhaba. PHP dizinizin içinde kimsenin görmemesi gereken bir veri yoksa dizinizi javascript'e iletmelisiniz. Böylece sayfa içinde dizinizdeki değerleri dilediğiniz gibi gösterebilirsiniz. (PHP dizinizdeki değerleri javascript'le değiştiremezsiniz. Javascript'le değiştirdiğiniz veriden PHP'nin haberi olmaz.)

<script>
    const vary_info = <?=json_encode($vary_info)?>;
    console.log(vary_info);
</script>

Eğer dizinizde çok büyük bir değer varsa bu yöntem performans kaybına neden olur. Söylediğiniz gibi sadece görüntüleneceği zaman ilgili veriyi ajax yardımıyla PHP'den istemek sayfanın açılış hızını olumlu etkileyecektir.
Ama yine söylediğiniz gibi bu sefer de aynı isteğin tekrar tekrar ajax ile PHP'den istenmesi sorunu olabilir. Bu da sunucuyu gereksiz yorar.
Sunucunun gereksiz yorulmasını önlemek için attığınız istekleri bir javascript değişkeninde tutabilirsiniz. Böylece aynı isteği yeniden atmanız gerektiğinde önce bu değişkeninize bakıp bu isteğin daha önce alınmış bir yanıtı olup olmadığını kontrol edersiniz ve gereksiz yere aynı isteği tekrar atmamış olursunuz. Yani attığınız her isteği cache'lemiş olursunuz.
Bunu yaptığınızda tarayıcının kullandığı ram miktarını bir miktar şişirmiş olursunuz. Eğer her bir istekten gelen veri çok büyük boyutluysa bu da çok ram harcamak demektir ama bence bu durum göz ardı edilebilir.
Eğer ram'in de çok şişmesini istemiyorsanız veriyi tarayıcının hafızasına kaydetmelisiniz. Yani bahsettiğiniz gibi local storage veya session storage burada size yardımcı olur. Tabi bunların 5'er mb sınırı (Chrome için) olduğunu da unutmamak lazım.
Eğer aldığınız veriyi session storage'a kaydedecekseniz önce string'e çevirmelisiniz çünkü bu storage'ler sadece string veri tutuyorlar.

<script>
    sessionStorage.setItem("vary_info", JSON.stringify(<?=json_encode($vary_info)?>));
    const vary_info = JSON.parse(sessionStorage.getItem(vary_info));
    console.log(vary_info);
</script>

Bu örnekte session storage'ı kontrol ederseniz verinizin orada tutulduğunu görebilirsiniz. Veriniz json formatına uygun olduğu için tarayıcınız size veriyi json gibi gösterebilir ama aslında tutulan veri string'dir. Bu yüzden kullanmak istediğiniz zaman JSON.parse() fonksiyonu ile string'i json'a dönüştürmelisiniz.
Bu örnekte veriyi ram'da tutmak yerine storage'da tuttuk diyebilir miyiz? Diyemeyiz. Sonuçta veriyi okumak için yine bir değişkene aktarıyoruz ve aynı veri ram'da da yer kaplıyor. Burada session storage'ın bize sağladığı şey, sayfa yenilense bile bu veriyi kaybetmeyecek olamız. Ama tarayıcı kapatıldığı zaman bu veri kaybolabilir.
Tarayıcı kapatıldığı zaman da veri saklansın istiyorsak session storage yerine local storage kullanabiliriz. Kullanımı session storage ile birebir aynı. yine .setItem(key, value) ve .getItem(key) fonksiyonlarına sahip.

Bana göre; PHP ile tüm verileri sayfaya çağırmak yerine sadece sayfa ilk yüklendiğinde görünecek olan verilerin sayfaya çekilmesi daha uygundur.
Eğer kullanıcı diğer verileri görecekse ajax isteği atılır ve PHP'den gerekli veriler istenir. Aynı zamanda yapılan istek ve isteğin sonucu bir js değişkeninde (ram'de) tutulur.
Her ajax isteğinde önce bu değişken kontrol edilir ve yeniden istek atılıp atılmayacağı buna göre belirlenir. Daha önce atılmış istek tekrar atılmaz. (ta ki sayfa yenilenenene kadar)
Bunu nasıl yaparız? Mesela bir select'in change olayıyla PHP'den veri isteyeceğiz diyelim:

// Yaptığımız istekleri cache'leyecek olan değişkenimiz:
const requests = [];

// #my-select id'li select elementinin change olayı tetiklendiğinde çalışacak fonksiyon:
$("select#my-select").on("change", function() {

    // Bu elemente kolayca (ajax fonksiyonu içinden de) erişebilmemiz için bir değişkene alıyoruz.
    const $this = $(this);
    
    // Ajax isteğimiz sonlanana kadar bu element'in kullanıcı tarafından tekrar değiştirilememesi gerekiyor. Elementi disabled edelim.
    $this.prop("disabled",true);
    
    // Kullanıcının seçtiği değeri alalım.
    const value = $this.val();
    
    // Ajax ile get isteği atılacak url'yi belirleyelim.
    const url = "newdata.php?value="+value;
    
    // Bu url'ye daha önce istek atılmış mı?
    const lastRequest = requests.find(function(request) { return request.url === url });
    
    // Eğer daha önce istek atılmışsa yeniden istek atmaya gerek olmadığı için veriyi direkt console'a yazdıralım.
    if(lastRequest) {
        console.log(lastRequest.data);
        alert("Bu istek daha önceden atıldığı için yeniden ajax isteği atılmadı. Elimizdeki veri console'a yazıldı.");
        
        // Bu adımdan sonra change olayının yapacağı başka bir işlem yok. select'in disabled değerini kaldırıp fonksiyonu return ile sonlandırabiliriz.
        $this.prop("disabled", false);
        return;
    };
    
    // Eğer buraya kadar geldiysek daha önce hiç istek atılmamış demektir. İsteği atabiliriz.
    $.ajax({
        url: url,
        type: "get",
        success: function(response) {
            // Verimizi başarıyla aldıysak gelen veriyi console'a yazdıralım.
            console.log(response);
            alert("İlk kez istek atıldı ve veriler alındı. Console'a yazıldı.");
            
            // Ayrıca bu veriyi cache'leyelim ki bi'daha bu istek atılmasın.
            requests.push({url: url, data: response});
        },
        error: function(err) {
            alert("Hata var!");
            console.error("Ajax isteğinden hata döndü: ", err);
        },
        complete: function() {
            // Olumlu veya olumsuz bir sonuç döndüğüne göre elementin disabled özelliğini kaldırabiliriz ki yeniden change edilebilsin.
            $this.prop("disabled", false);
        }
    });
});

Kodları test etmeden yazdığım için hatalar olabilir. Ama aşağı yukarı kurgusal bir cevap yazdım sanıyorum. :)