1

I am trying to get weather result on select value change, I tried to many posts like : This one and some more. but couldn't make it work.

I know it seems easy, but I couldnt get over it, I get this error but code works fine if I dont use select box.

Notice: Undefined offset: 1 in C:\wamp64\www\test\modules\weather.php on line 10

I want to update this div with two fields in it $image and $dayTime value:

<div class="col-md-6">
  <span id="wthr" class="float-md-left">
    <img src="<?php echo $image[1]; ?>" width="20" height="20"/>
    <?php echo $dayTime[1]; ?>
  </span>
</div>

Codes in index.php Cities :

$cities = array('adana' => 'ADANA', 'adiyaman' => 'ADIYAMAN', 'afyon' => 'AFYON',
    'agri' => 'AĞRI', 'aksaray' => 'AKSARAY', 'amasya' => 'AMASYA', 'ankara' => 'ANKARA',
    'antalya' => 'ANTALYA', 'ardahan' => 'ARDAHAN', 'artvin' => 'ARTVİN', 'aydin' => 'AYDIN'
    );

<div class="col-md-6">
    <span class="float-md-right">
        <select name="city" class="weather" id="city">
        <?php foreach($cities as $key => $value){
        echo '<option value="'.$key.'">'.$value.'</option>';
        }
        ?>
        </select>
    </span>
</div>

Ajax post :

$('#city').change(function(event) {
        event.preventDefault();
    $.post('modules/weather.php', { selected: $('#city').val() },
        function(data) {
            $('#wthr').html(data);
        }
    );            
});

And weather.php which is in another folder /modules/weather.php

$city = $_GET['city'];
$data = [];

$url="http://www.mynet.com/havadurumu/asya/turkiye/".$city;
$source = file_get_contents($url);
preg_match('@<p class="hvPboxMiddle">(.*?)<\/p>@si',$source,$result);
preg_match('@<span class="hvDay">(.*?)<\/span>@si',$result[1],$day);
preg_match('@<span class="hvMood">(.*?)<\/span>@si',$result[1],$situation);
preg_match('@<span class="hvDeg1">(.*?)<\/span>@si',$result[1],$dayTime);
preg_match('@<span class="hvDeg2">(.*?)<\/span>@si',$result[1],$nightTime);
preg_match('@<img src="(.*?)" alt="(.*?)" />@si',$result[1],$image);

$data[] = $image[1] . $dayTime[1];
echo json_encode($data);
Christos Lytras
  • 36,310
  • 4
  • 80
  • 113
  • 1
    You're making a POST request but using $_GET and sending `selected` as the parameter but using `city`? – Musa Aug 21 '21 at 16:34
  • I was using POST but tried GET is well and forgot to change back it didnt make difference, thought **selected** posts value to other page no ? –  Aug 21 '21 at 16:39
  • I would recommend not using regular expressions for HTML scraping. Perhaps use a method mentioned here: https://stackoverflow.com/questions/9813273/web-scraping-in-php If you want to use regex, make sure to test your regex code using something like https://regex101.com/ – segFault Aug 21 '21 at 16:51
  • You may want to use `https://www.mynet.com/havadurumu/asya/turkiye/` in your intial request, checking the insecure `http://` URL, yields a `HTTP/1.1 301 Moved permanently` – segFault Aug 21 '21 at 16:56
  • @segFault Mynet response in both but I will change it once I make code work. thanks –  Aug 21 '21 at 17:00

1 Answers1

0

There are several issues with your implementation.

  1. You are using Regular Expressions for HTML scraping; it may work with HTML cases you're actually seeing, but it may break for HTML code that you haven't seen yet. A use of an HTML scraper is suggested but this code works for now.
  2. You are getting this error on weather.php on line 10, because there is no data, because there is no city in $_GET nor $_POST array data, because you're actually passing a POST parameter with the name of selected rather than city name that your PHP fetch script is using.
  3. You are trying to present/echo PHP data/variables when you are doing an AJAX request fetching some JSON data from the server; you either fetch JSON and update selected HTML elements with that specific data, or just return HTML code to replace the HTML code inside the #wthr element.

Fully working code

index.php

<?php

$cities = array(
  'adana' => 'ADANA',
  'adiyaman' => 'ADIYAMAN',
  'afyon' => 'AFYON',
  'agri' => 'AĞRI',
  'aksaray' => 'AKSARAY',
  'amasya' => 'AMASYA',
  'ankara' => 'ANKARA',
  'antalya' => 'ANTALYA',
  'ardahan' => 'ARDAHAN',
  'artvin' => 'ARTVİN',
  'aydin' => 'AYDIN'
);

?>
<html>
  <head>
    <title>PHP Test</title>
  </head>
  <body>
    <div class="col-md-6">
      <span class="float-md-right">
        <select name="city" class="weather" id="city">
        <?php foreach ($cities as $key => $value): ?>
          <option value="<?= $key ?>"><?= $value ?></option>
        <?php endforeach; ?>
        </select>
      </span>
    </div>

    <div class="col-md-6">
      <span id="wthr" class="float-md-left">
      <!--
        We don't include any elements here,
        because we're going to return
        the entire HTML code from the server.

        <img src="<?= $image[1] ?>" width="20" height="20"/>
        <?= $dayTime[1] ?>

      -->
      </span>
    </div>

    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script>
      $('#city').change(function(event) {
        event.preventDefault();

        $.post(
          'weather.php',
          {
            // Here we pass the correct/expected parameter name
            // to the server script which is `city`
            city: $('#city').val()
          },
          function (data) {
            // We get raw HTML code from the server,
            // so we can update the entire element HTML code.
            $('#wthr').html(data);
          }
        );            
      });

      $(function () {
        // Update with the first selected city on page initial load.
        $('#city').trigger('change');
      });
    </script>
  </body>
</html>

weather.php

<?php

$city = $_POST['city'];
$data = [];

$url="http://www.mynet.com/havadurumu/asya/turkiye/".$city;
$source = file_get_contents($url);



preg_match('@<p class="hvPboxMiddle">(.*?)<\/p>@si', $source, $result);
preg_match('@<span class="hvDay">(.*?)<\/span>@si', $result[1], $day);
preg_match('@<span class="hvMood">(.*?)<\/span>@si', $result[1], $situation);
preg_match('@<span class="hvDeg1">(.*?)<\/span>@si', $result[1], $dayTime);
preg_match('@<span class="hvDeg2">(.*?)<\/span>@si', $result[1], $nightTime);
preg_match('@<img src="(.*?)" alt="(.*?)" />@si', $result[1], $image);

// $data[] = $image[1] . $dayTime[1];
// echo json_encode($data);

// Here we return the first element of the $image array
// that is a ready made HTML IMG element and we concatenate the $dayTime[1]
// which by the way is just retrieving the temperature in celcius degrees
// (class="hvDeg1" seems incorect for a $dayTime value).

die($image[0]."<span>{$dayTime[1]}</span>");

Fully working online replit

You can check the fully working code onto this Replit: https://replit.com/@ChristosLytras/CuddlyRaggedTransfer#index.php

Christos Lytras
  • 36,310
  • 4
  • 80
  • 113
  • Thanks for the answer and explanition, I dont use this as it is in question, This was needed for something else and I didnt want to ask a new question bcoz its almost same. I am getting data from mynet and inserting it in to database and listing from database. I use simple DOM. Thank you again I will forward award in 13 hours. –  Aug 24 '21 at 09:10