1

私は現在、さまざまなソーシャル ネットワークのリンクを統合するツールに取り組んでいます。

Facebook: https://www.facebook.com/jonathan.parentlevesque

Google plus: https://plus.google.com/+JonathanParentL%C3%A9vesque

Instagram: https://instagram.com/mariloubiz/

Pinterest: https://www.pinterest.com/jonathan_parl/

RSS: https://regex101.com

Twitter: https://twitter.com/arcadefire

Vimeo: https://vimeo.com/ondemand/crashtest/135301838

Youtube: https://www.youtube.com/user/Darkjo666

私はこのような非常に基本的な正規表現を使用しています:

/^https?:\/\/(?:[a-z]{2}|[w]{3})?\.pinterest.com\/[\S]{5,}$/i

クライアント側とサーバー側で、各リンクで最小限のドメイン検証を行います。

次に、この関数を使用して、ページが実際に存在することを検証しています (結局機能しないソーシャル ネットワーク リンクを統合しても意味がありません)。

public static function isUrlExists($url){

    $exists = false;

    if(!StringManager::stringStartWith($url, "http") and !StringManager::stringStartWith($url, "ftp")){

        $url = "https://" . $url;
    }

    if (preg_match(RegularExpression::URL, $url)){

        $headers = get_headers($url);

        if ($headers !== false and !empty($headers)){

            if (strpos($headers[0], '404') === false){

                $exists = true;
            }   
        }
    }

    return $exists;
}

: この関数では、リクエストを送信する前に URL を検証するために Diego Perini の正規表現を使用しています。

const URL = "%^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@|\d{1,3}(?:\.\d{1,3}){3}|(?:(?:[a-z\d\x{00a1}-\x{ffff}]+-?)*[a-z\d\x{00a1}-\x{ffff}]+)(?:\.(?:[a-z\d\x{00a1}-\x{ffff}]+-?)*[a-z\d\x{00a1}-\x{ffff}]+)*(?:\.[a-z\x{00a1}-\x{ffff}]{2,6}))(?::\d+)?(?:[^\s]*)?$%iu"; //@copyright Diego Perini

これまでにテストしたすべてのリンクでエラーは発生しませんでしたが、Pinterest をテストすると、次の非常に恐ろしい一連のエラー メッセージが表示されます。

get_headers(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

Array
(
    [url] => https://www.pinterest.com/jonathan_parl/
    [exists] => 
)

get_headers(): Failed to enable crypto

Array
(
    [url] => https://www.pinterest.com/jonathan_parl/
    [exists] => 
)

get_headers(https://www.pinterest.com/jonathan_parl/): failed to open stream: operation failed

Array
(
    [url] => https://www.pinterest.com/jonathan_parl/
    [exists] => 
)

ここで私が間違っていることを知っている人はいますか?

つまり、Pinterest は有効な証明書を持つ人気のあるソーシャル ネットワークではありませんか (個人的には使用していません。テスト用にアカウントを作成しただけです)。

ご協力ありがとうございました、

モントリオール出身のジョナサン・パレント・レベスク

4

1 に答える 1

2

NBの提案に従って、開発環境 (Xampp) 用の自己署名証明書を作成しようとしました。彼のコメントで。その解決策は私にはうまくいきませんでした。

彼の他の解決策は、get_headers() の代わりに cUrl または guzzle を使用することでした。機能しただけでなく、この開発者のテストによると:

http://php.net/manual/fr/function.get-headers.php#104723

また、get_headers() よりもはるかに高速です。

興味のある人のために、興味のある人のための私の新しい関数のコードは次のとおりです。

/**
* Send an HTTP request to a the $url and check the header posted back.
*
* @param $url String url to which we must send the request.
* @param $failCodeList Int array list of codes for which the page is considered invalid.
*
* @return Boolean
*/
public static function isUrlExists($url, array $failCodeList = array(404)){

    $exists = false;

    if(!StringManager::stringStartWith($url, "http") and !StringManager::stringStartWith($url, "ftp")){

        $url = "https://" . $url;
    }

    if (preg_match(RegularExpression::URL, $url)){

        $handle = curl_init($url);


        curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);

        curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);

        curl_setopt($handle, CURLOPT_HEADER, true);

        curl_setopt($handle, CURLOPT_NOBODY, true);

        curl_setopt($handle, CURLOPT_USERAGENT, true);


        $headers = curl_exec($handle);

        curl_close($handle);


        if (empty($failCodeList) or !is_array($failCodeList)){

            $failCodeList = array(404); 
        }

        if (!empty($headers)){

            $exists = true;

            $headers = explode(PHP_EOL, $headers);

            foreach($failCodeList as $code){

                if (is_numeric($code) and strpos($headers[0], strval($code)) !== false){

                    $exists = false;

                    break;  
                }
            }
        }
    }

    return $exists;
}

curl オプションについて説明します。

CURLOPT_RETURNTRANSFER : 呼び出しページを画面に表示する代わりに文字列を返します。

CURLOPT_SSL_VERIFYPEER : cUrl は証明書をチェックアウトしません

CURLOPT_HEADER : 文字列にヘッダーを含めます

CURLOPT_NOBODY : 文字列に本文を含めないでください

CURLOPT_USERAGENT : 一部のサイトでは、正しく機能するためにそれが必要です (例: https://plus.google.com )


追加メモ: ヘッダー文字列とユーザー ヘッダー [0] を展開して、リターン コードとメッセージのみを検証するようにします (例: 200、404、405 など)。

追記 2 : コード 404 のみを検証するだけでは不十分な場合があるため (単体テストを参照)、拒否するすべてのコード リストを提供するオプションの $failCodeList パラメーターがあります。

そしてもちろん、私のコーディングを正当化するための単体テストは次のとおりです。

public function testIsUrlExists(){

//invalid
$this->assertFalse(ToolManager::isUrlExists("woot"));

$this->assertFalse(ToolManager::isUrlExists("https://www.facebook.com/jonathan.parentlevesque4545646456"));

$this->assertFalse(ToolManager::isUrlExists("https://plus.google.com/+JonathanParentL%C3%A9vesque890800"));

$this->assertFalse(ToolManager::isUrlExists("https://instagram.com/mariloubiz1232132/", array(404, 405)));

$this->assertFalse(ToolManager::isUrlExists("https://www.pinterest.com/jonathan_parl1231/"));

$this->assertFalse(ToolManager::isUrlExists("https://regex101.com/546465465456"));

$this->assertFalse(ToolManager::isUrlExists("https://twitter.com/arcadefire4566546"));

$this->assertFalse(ToolManager::isUrlExists("https://vimeo.com/**($%?%$", array(400, 405)));

$this->assertFalse(ToolManager::isUrlExists("https://www.youtube.com/user/Darkjo666456456456"));


//valid
$this->assertTrue(ToolManager::isUrlExists("www.google.ca"));

$this->assertTrue(ToolManager::isUrlExists("https://www.facebook.com/jonathan.parentlevesque"));

$this->assertTrue(ToolManager::isUrlExists("https://plus.google.com/+JonathanParentL%C3%A9vesque"));

$this->assertTrue(ToolManager::isUrlExists("https://instagram.com/mariloubiz/"));

$this->assertTrue(ToolManager::isUrlExists("https://www.facebook.com/jonathan.parentlevesque"));

$this->assertTrue(ToolManager::isUrlExists("https://www.pinterest.com/"));

$this->assertTrue(ToolManager::isUrlExists("https://regex101.com"));

$this->assertTrue(ToolManager::isUrlExists("https://twitter.com/arcadefire"));

$this->assertTrue(ToolManager::isUrlExists("https://vimeo.com/"));

$this->assertTrue(ToolManager::isUrlExists("https://www.youtube.com/user/Darkjo666"));
}

この解決策が誰かに役立つことを願っています、

モントリオール出身のジョナサン・パレント・レベスク

于 2015-08-19T20:59:43.047 に答える