0

I have a Matrix table generated in PHP. And I want to show a "check" or a "cross" based on result of a DNS call. This table Matrix can contain more than 200.000 cells.

I've tried to put all PHP code on same page, but the PHP go timeout if there are many DNS calls to do. I moved on to ajax. Added a DIV inside each cell and put the ajax code calling a 2nd PHP which will do the DNS query. This works well, but after 5000-6000 requests, some cells aren't populated. My guess is because the script is trying to make calls for all cells at the same time.

Is it a way to get ajax doing calls for each cell one at time?

I have this PHP code:

$body .= '
  <script type="text/javascript">
';

foreach (getEachIpInRange($cidr) as $IP) {
    foreach ($rbls as $rbl) {
        $divid++;
        $body .= '    function updatediv' . $divid . '() {
      $.ajax({
        type: \'get\',
        url: \'verify.php?ip=' . $IP . '&dns=' . $rbl . '\',
        data: $(self).serialize(),
        success: function(data) {
          $("#div'  . $divid .  '").html(data).text();
        }
      })
    }
';
    }
}

$body .= '  </script>
';

That generates the following code:

  <script type="text/javascript">
    function updatediv1() {
      $.ajax({
        type: 'get',
        url: 'verify.php?ip=123.123.123.123&dns=host.domain1.tld',
        data: $(self).serialize(),
        success: function(data) {
          $("#div1").html(data).text();
        }
      })
    }
    function updatediv2() {
      $.ajax({
        type: 'get',
        url: 'verify.php?ip=234.234.234.234&dns=host.domain2.tld',
        data: $(self).serialize(),
        success: function(data) {
          $("#div2").html(data).text();
        }
      })
    }
    function updatediv3() {
      $.ajax({
        type: 'get',
        url: 'verify.php?ip=345.345.345.345&dns=host.domain3.tld',
        data: $(self).serialize(),
        success: function(data) {
          $("#div3").html(data).text();
        }
      })
    }
    function updatediv4() {
      $.ajax({
        type: 'get',
        url: 'verify.php?ip=456.456.456.456&dns=host.domain4.tld',
        data: $(self).serialize(),
        success: function(data) {
          $("#div4").html(data).text();
        }
      })
    }

The best would be a single function that will update each cell one after the other. But if not possible, how can I loop between all functions and run them, giving like 25ms or 30ms of interval between each of them to not get a timeout?

3
  • This is an awfully convoluted way to code. Functions can take parameters and since they are identical sans whatever few values, you can have one function that takes whatever values are needed to complete the operation. Commented Oct 4, 2019 at 15:21
  • 2
    "This works well, but after 5000-6000 requests, some cells aren't populated. My guess is because the script is trying to make calls for all cells at the same time" this is quite wasteful, as well - why not just send the entire data at once, instead of one per cell? Firing literally thousands of requests at once seems really excessive. Commented Oct 4, 2019 at 15:23
  • VLAZ, i know and i am aware of that. I am not a specialist in javascript or ajax. That is why i came here to ask this question. Commented Oct 4, 2019 at 15:35

3 Answers 3

2

Please do not generate one function for each cell; that's bloated. Just create one function that takes a number as a parameter and uses that to make the right call, select the right cell, etc.

function updatediv(n) {
  const ipPart = `${n}${n+1}${n+2}`;
  $.ajax({
    type: 'get',
    url: `verify.php?ip=${ipPart}.${ipPart}.${ipPart}.${ipPart}&dns=host.domain${n}.tld`,
    data: $(self).serialize(),
    success: function(data) {
      $(`#div${n}`).html(data).text();
    }
  })
}

From there, you can just do a simple for loop and call the function for each value of n.

Sign up to request clarification or add additional context in comments.

3 Comments

The IP and dns part was just examples, I have an array in PHP with the IPs and another with the dns hosts. It's not something that is just a +1.
@Webix doesn't change much, though - give the data to JS and you'll be able to use it in the function.
@Webix So have the PHP output its array as a JS array and then iterate through that array in JS with a forEach loop? The point is don't make a separate function for every single element. We can't give you more specific help if we don't know what type of data you're actually using.
0

Starting from @IceMetalPunk solution for avoid problem with concurrent calls you can do a thing like these

function updatediv(n) {
  const ipPart = `${n}${n+1}${n+2}`;
  $.ajax({
    type: 'get',
    url: `verify.php?ip=${ipPart}.${ipPart}.${ipPart}.${ipPart}&dns=host.domain${n}.tld`,
    data: $(self).serialize(),
    success: function(data) {
      $(`#div${n}`).html(data).text();
      if(n < MAX_N)
        updatediv(n+1);
    }
  })
}

or if recursion create problem create an hidden DOM object to activate

<div id="hide_action" onClick="updatediv($('#hide_count').val());" style="display: none;"></div>

and change function with

if(n < MAX_N){
    $('#hide_count').val(n+1);
    $('#hide_action').click();
}

2 Comments

mYmage. Like i reply to @IceMetalPunk, the IP and dns part is merely examples. I have an array in PHP with the IPs and another with the dns.
Create a list of hidden object for IP and one for DNS with class selector like: <div id="ip_1" class="ip_list">ip_value_1</div> ... <div id="ip_n" class="ip_list">ip_value_n</div> <div id="dns_1" class="dns_list">dns_value_1</div> ... <div id="dns_n" class="dns_list">dns_value_n</div> then use class/id to get data you need
0

Ok folks. I successfully solved my own problem after a lot of research. 1st, i can't load everything at once. The PHP will just go timeout or the browser goes unresponsive.

I had to load up the ips and dns on different javascript arrays from PHP. So, i came up with this code:

function updatediv(divid,ip,rbl) {
  $.ajax({
    type: \'get\',
    url: `verify.php?ip=${ip}&rbl=${rbl}`,
    data: $(self).serialize(),
    success: function(data) {
      $(`#div${divid}`).html(data).text();
    }
  });

}

function looptable () {
    var divid=1;
    for (var a=0;a<=arrayIPs.length;a++) {
        (function (a) {
            setTimeout(function () {
              for (var b=0;b<=arrayRBLs.length;b++) {
                (function (b) {
                    setTimeout(function () {
                      updatediv(divid,arrayIPs[a],arrayRBLs[b]);
                      divid++;
                    }, 50*b);
                })(b);
              }
            }, 50*a*arrayRBLs.length);
        })(a);
    }
}
looptable();

This code will fill up the table cell-by-cell by calling the 2nd PHP with 50ms interval, so the system doesn't get overloaded. Let me know what you guys think.

Regards

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.