【问题标题】:My PHP code is very slow, how to make it fast? [closed]我的 PHP 代码很慢,如何让它变快? [关闭]
【发布时间】:2021-02-10 15:23:48
【问题描述】:

为什么我的代码很慢,如果我删除所有东西以获取这些元标记,代码变得超级快,但我不知道 OOP。

在我添加了从 URL 获取元标记的功能后,它非常好。我不知道是 SQL 让它变慢了,还是 get_meta_tags 函数。

<?php
$servername = "localhost";
$username = "phpmyadmin";
$password = "supersu";
$starttime = time();
function cape($url,$depth=5) {
    if($depth>0) {
        $html = file_get_contents($url);
        $pattern = '~<a.*?href="(.*?)".*?>~'; 
        preg_match_all($pattern, $html, $matches); 
        foreach($matches[1] as $newurl) { 
            // do stuff 
            $regex = "((https?|ftp)\:\/\/)?"; 
            // SCHEME 
            $regex .= "([a-z0-9+!*(),;?&=\$_.-]+(\:[a-z0-9+!*(),;?&=\$_.-]+)?@)?"; 
            // User and Pass 
            $regex .= "([a-z0-9-.]*)\.([a-z]{2,3})"; 
            // Host or IP 
            $regex .= "(\:[0-9]{2,5})?"; 
            // Port 
            $regex .= "(\/([a-z0-9+\$_-]\.?)+)*\/?"; 
            // Path 
            $regex .= "(\?[a-z+&\$_.-][a-z0-9;:@&%=+\/\$_.-]*)?"; 
            // GET Query 
            $regex .= "(#[a-z_.-][a-z0-9+\$_.-]*)?"; 
            // Anchor 
            // `i` flag for case-insensitive
            if(preg_match("/^$regex$/i", $newurl))  {
                if(substr($newurl, -1) !== "/") { 
                    $newurl = $newurl . "/"; 
                } 
                try { 
                    $tags = get_meta_tags($newurl); 
                    $desc = file_get_contents($newurl); 
                    $password = "supersu"; 
                    $username = "phpmyadmin"; 
                    $conn = new PDO("mysql:host=localhost;dbname=supersu", $username, $password); 
                    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
                    if(isset($tags['description'])) { 
                        $conn->exec( 'INSERT INTO snapd (link,Description) SELECT * FROM (SELECT "'.$newurl.'","'.$tags['description'].'") AS tmp WHERE NOT EXISTS ( SELECT link FROM snapd WHERE link = "'.$newurl.'" ) LIMIT 1' );
                        echo $newurl; 
                    } else { 
                        $conn->exec( 'INSERT INTO snapd (link,Description) SELECT * FROM (SELECT "'.$newurl.'","No Info") AS tmp WHERE NOT EXISTS ( SELECT link FROM snapd WHERE link = "'.$newurl.'" ) LIMIT 1' ); 
                        echo $newurl; 
                    } 
                } catch(PDOException $e) { 
                    echo "Connection failed: " . $e->getMessage(); 
                } 
                cape($newurl,$depth-1); 
            } 
        } 
    } 
} 
cape("https://techdeploy.xyz"); 
?>

【问题讨论】:

  • “我不知道是 SQL 让它变慢了,还是 get_meta_tags 函数。” - 可能是后者,因为 HTTP 请求占用(相当)大量时间。
  • 调试的第一步是编写可读代码,例如在每条指令上添加新行。
  • 如果我没看错的话,这段代码会获取一个 URL,然后以递归方式将它在该页面中找到的 所有 个 URL 爬行到五页的深度?我不知道第一页的结构,但感觉可能是大量的请求。
  • @iainn 是的,你没看错,但是在不使用 get_meta_contents 然后将其上传到数据库的情况下,它运行得非常快,但是使用这个函数并将内容上传到数据库中,这个脚本变得非常慢.每 2 秒有 1 个网址,然后是每 2 秒 15-20 个网址。
  • 这非常接近于尝试parse HTML with a regex

标签: php


【解决方案1】:
  1. 您正在使用正则表达式解析 HTML。提供using DOM functions 可能会更好(几乎可以肯定,还有一个比正则表达式更好的用于从 URL 解析组件的库)。
  2. get_meta_tagsfile_get_contents 都向同一个 URL 发出 HTTP 请求。发出一次请求,缓存结果,然后对该结果进行处理。
  3. 您正在为处理的每个页面创建一个新的数据库连接,最好在函数执行期间保持一个连接打开。
  4. 您直接将字符串插入到数据库查询中。这是难以置信不安全的(特别是当字符串来自其他人的服务器时)。使用prepared statements 会更安全更快。
  5. 我不知道 php 的异步 IO 支持的状态是什么(我怀疑不是很好),但是如果有办法同时触发一些请求然后处理结果会明显更快(尽管它会占用更多内存)。

【讨论】:

    猜你喜欢
    • 2015-07-26
    • 1970-01-01
    • 2017-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-16
    • 2012-12-08
    相关资源
    最近更新 更多