doulin6761 2014-12-15 13:34
浏览 77
已采纳

共享主机具有固定的最大执行时间; 我的管理员PHP脚本超过了

My client is an entrepeneur and has no html knowledge. He has a website that was created with PHP on a linux shared hosting environment (basic package). On his site he wants to show his previous jobs with photos. But he complains he finds it to hard to login as admin and uploads those photos himself.

-now he asks me to write something easy for him so that the photos in his Dropbox account are uploaded on his site. I said OK :)

I created an admin page ( Here my client can choose which dropbox album he wants to download to his site. ) -I have used the dropbox api for php to locate his photo-albums. -I made a form where I list those albums with submit buttons that will do a POST-request(parameter = path to file on dropbox account).

Here is the code for that request:

if (isset($_POST['AlbumAdd'])) { 
    $name = $_POST['AlbumAdd'];
    //echo "submitted: $name <br>";
    $entry = getClient()->getMetadataWithChildren($name); //dropbox-sdk 
    if ($entry['is_dir']) {

        //for now create file on localhost -> replace with ftp to upload on shared hosting site
        if (!file_exists(__DIR__ . "/../examples/folder" . $name)) { //if !excists create folder on localhost
            mkdir(__DIR__ . "/../examples/folder" . $name, 0777, true);
            //echo "created " . $name  . "on localhost";
        } 
        foreach ($entry['contents'] as $child) {
            $cp = $child['path'];
            $size = $child['size'];
            $cn = basename($cp);
            echo "basename (cn)= " . $cn . " [$size] <br>";
            if (!$child['is_dir']) //files only
            {
                //download from dropbox to localhost 
                getClient()->getFile($cp, fopen(__DIR__ . '/../examples/folder' . $cp, 'w+b'));
            }
        }
    }
}

This works fine for small files, but throws this exception when the album is too large:

Fatal error: Maximum execution time of 30 seconds exceeded in C:\wamp\www\dropbox-sdk-php-1.1.4\dropbox-sdk\Dropbox\CurlStreamRelay.php on line 26
TEST OUTPUT:
basename (cn)= 01.mp3 [8.1 MB]
basename (cn)= 02.mp3 [7.3 MB]
basename (cn)= 03.mp3 [6 MB] 

What is the best thing to do now?? -Helpdesk of the hosting site says they can't change the setting of the maximum execution time. So there is no point in changing my php.ini file.

-upload each photo individually?

-switching to dedicated server means I have full control? I don't know if my client likes to pay 125€ extra/month

  • 写回答

2条回答 默认 最新

  • doulai8128 2014-12-15 15:09
    关注

    I think you should refactor your logic, using also some client-side logic...
    You should first download the structure of remote folder (with getMetadataWithChildren()), and store it on disk with some kind of indexing (i.e.: assigning each file/dir to be downloaded a unique id). This task should hopefully terminate within the maximum execution time limit set by your provider...
    Then you should build a second script to download the real data, reading the previously downloaded index, one file/dir at a time.
    The script should catch the "MAXIMUM EXECUTION TIME" error to signal it has not yet finished it's job... Something like this:

    File: "download_data_from_dropbox.php"

    <?php
      register_shutdown_function('shutdown');
    
      global $id;
      DOWNLOAD_DATA($id);
      echo json_encode(array("done" => 1);
      exit 0;
    
      function shutdown() {
        $e = error_get_last();
        if ($e == "max_execution_time") {
          echo json_encode(array("lastId" => $id);
          exit 0;
        }
      }
    ?>
    

    Then, you should call the php script to download data from dropbox repeatedly, until it finishes:

    File "index.html":

    <html>
      <head>
      </head>
      <body>
      ...
      <div id="status"></div>
      ...
      <script>
      $(document).ready(function() {
          var done = false, id = '',
          while (!done) {
              var url = "download_data_from_dropbox.php?id=" + id;
              $.ajax({
                  url: url,
                  dataType: 'json',
              }).done(function(response) {
                  if (response.done === 1) {
                      // php script is done
                      done = true;
                  }
                  $("#status").html("Downloading data, last file ID is " + response.lastId   + " ...");
              }).fail(function(jqXHR, textStatus) {
                  $("#mybox").html("Error while downloading data: " textStatus);
                  done = true;
              });
          }
      });
      </script>
      </body>
    </html>
    

    Note: this code is a simple attempt to show a possible solution, it contains some pseudocode, it's not at all finished, and, of course, untested... :-) You should also probably use setInterval(), instead of the while (!done) loop, in javascript code...

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 unity第一人称射击小游戏,有demo,在原脚本的基础上进行修改以达到要求
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染