Laravel Türkiye Discord Kanalı Forumda kod paylaşılırken dikkat edilmesi gerekenler!Birlikte proje geliştirmek ister misiniz?

Aşağıdaki kodlara sahibim. Bir veritabanından kayıtlı url leri cekıyorum. örnek🙁https://wordpres.com.tr/category/seo/feed)
Bu sayfalar xml (rss feed) categori sayfaları. Bu sayfalardaki konu başlığı ve linkini alıyorum, veritabanıma ekliyorum.
@mgsmus beyefendi sayesinde kodum çok güzel çalışıyor.
Sıkıntım şu, çektiğim başlık ve urlelerden birisi daha önce kaydedildiyse, doğal olarak kaydetmesin istiyorum. Bunun için
$date= $article->pubDate;
$sontarih = DB::table('bot')
->latest('created_at')->first();
if($date < $sontarih->created_at){.

bu şekilde bir yaklaşımda bulundum. Ama hiç kayıt yoksa hata veriyor. kayıt varsada doğru çalıştığına dair süpheliyim.
Bir diğer kafama takılan şey ise bir sayfa artık yoksa, yani 404 cevirirse ne olacak. o sayfayı atlar devam mı eder. hata verip tüm işlem başarısızmı olur. Başarısız oluyorsa bunun için ne yapmam lazım.

KODUN TAMAMI :

        ->toArray();
        $client = new Client();
        $promises = (function () use ($urls, $client) {
            foreach ($urls as $url) {
                yield $client->getAsync($url,[ 'http_errors'  =>  false ], [ 'timeout'  =>  300 ]);
            }
        })();   


    (new EachPromise($promises, [
        'concurrency' => 10,
        'fulfilled' => function (ResponseInterface $response, int $index) {
            $index =  $response->getBody()->getContents();
            $feed = simplexml_load_string($index);
            
foreach ($feed->channel->item as $article) { $date= $article->pubDate; $sontarih = DB::table('bot') ->latest('created_at')->first(); if($date < $sontarih->created_at){ DB::table('bot')->insert([ 'baslik' => $article->title, 'url' => $article->link, 'created_at' => Carbon::now(), 'updated_at' => Carbon::now() ]); } } } ]))->promise()->wait();```

    aeneas

    aeneas Bir diğer kafama takılan şey ise bir sayfa artık yoksa, yani 404 cevirirse ne olacak. o sayfayı atlar devam mı eder. hata verip tüm işlem başarısızmı olur. Başarısız oluyorsa bunun için ne yapmam lazım.

    $response->getStatusCode() size http status kodunu verir. $response->getStatusCode() != 200 ise diye kontrol ekleyeceksiniz.

    aeneas Sıkıntım şu, çektiğim başlık ve urlelerden birisi daha önce kaydedildiyse, doğal olarak kaydetmesin istiyorum.

    Bunu yapmanın birden fazla yolu var. Size race-condition problemi yaşatmayacak şekilde olanlardan biri unique index kullanmak. bot tablonuza baslik ve url için unique index ekleyeceksiniz:

    Eğer ikisi bağımsız bir şekilde benzersiz olsun istiyorsanız:

    $table->unique('baslik');
    $table->unique('url');

    Bu şekilde başlık A bir kere eklendi mi bir daha eklenmez, url B bir kere eklendi mi bir daha eklenmez. Eğer her ikisi birlikte engellemek istiyorsanız, yani şuna izin vermek istiyorsanız:

    +--------+-----+
    | baslik | url |
    +--------+-----+
    | A      | B   |
    | A      | C   |
    +--------+-----+

    birleşik index ekleyeceksiniz:

    $table->unique(['baslik', 'url']);

    Böyle yaptığınızda girişe engel olursunuz ama doğal olarak duplicate record hatası alacaksınız. Bu hatayı try...catch ile de yakalayıp işlem yapabilirsiniz ya da hata vermesin yeter derseniz insert yerine insertOrIgnore kullanabilirsiniz.

      mgsmus $response->getStatusCode() != 200 kullandıgımda 404 ceviren bir url var ise 200 hata kodu yakalıyorum peki ulasılamıyan url veya urlleri de yakalıyabilirmiyim.

      Birde $response->getStatusCode() != 200 ile tüm hataları yakalıyabilirmiyim. 404 , 500 vs gibi yoksa ClientException ve ServerException mi kullanmak daha sağlıklı olur.

        aeneas Bu dediğinizden hiçbir şey anlamadım 🙂 $response->getStatusCode() integer olarak istek atılan sunucunun verdiği http kodunu veriyor. 200 başarılı demek, 200 değilse demek ki bir şey yanlış gitmiş demektir. Bu 3xx, 4xx, 5xx kodlarından biri olabilir, sonuçta 200 değil. Http durum kodlarının ne olduğunu bilmiyorsanız araştırın:
        https://developer.mozilla.org/en-US/docs/Web/HTTP/Status

        Yanıt 200 olsa da gelen içerik sizin istediğiniz gibi olmayabilir, boş olabilir vs onu yanıtı işlerken ayrı kontrol edersiniz.

          5 gün sonra

          mgsmus çok teşekkür ederim. İnsertorignore kayit sorununu çözdü. Fakat linkleri eklerken bir denetimden geçirmek istiyorum, linkin bir RSS feed sayfası olduğunu ve 404 500 gibi hatalar vermeyen aktif bir link olduğunu kayıt esnasında kontrol etmek istiyorum. Bunu bir türlü başaramadım

            aeneas simplexml_load_string() kullanmışsınız. İçeriye verdiğiniz string geçerli bir XML değilse hata vermez ama warning verir. O uyarıları engelleyip kontrol yapabilmek için libxml_use_internal_errors(true) kullanmanız gerekiyor.
            https://www.php.net/manual/en/function.libxml-use-internal-errors.php

            Yani:

            // Sunucu başarılı yanıt vermiş ise
            if($response->getStatusCode() === 200) {
                libxml_use_internal_errors(true);
            
                // $feed geçerli bir XML ise
                if($feed = simplexml_load_string($index)) {
                    // $feed bir RSS ise
                    if($feed->channel) {
                        // İşlemler...
                    }
                }
            }