PHP validation/regex for URL

后端 未结 21 2059
青春惊慌失措
青春惊慌失措 2020-11-22 01:19

I\'ve been looking for a simple regex for URLs, does anybody have one handy that works well? I didn\'t find one with the zend framework validation classes and have seen sev

21条回答
  •  一向
    一向 (楼主)
    2020-11-22 02:01

    Inspired in this .NET StackOverflow question and in this referenced article from that question there is this URI validator (URI means it validates both URL and URN).

    if( ! preg_match( "/^([a-z][a-z0-9+.-]*):(?:\\/\\/((?:(?=((?:[a-z0-9-._~!$&'()*+,;=:]|%[0-9A-F]{2})*))(\\3)@)?(?=(\\[[0-9A-F:.]{2,}\\]|(?:[a-z0-9-._~!$&'()*+,;=]|%[0-9A-F]{2})*))\\5(?::(?=(\\d*))\\6)?)(\\/(?=((?:[a-z0-9-._~!$&'()*+,;=:@\\/]|%[0-9A-F]{2})*))\\8)?|(\\/?(?!\\/)(?=((?:[a-z0-9-._~!$&'()*+,;=:@\\/]|%[0-9A-F]{2})*))\\10)?)(?:\\?(?=((?:[a-z0-9-._~!$&'()*+,;=:@\\/?]|%[0-9A-F]{2})*))\\11)?(?:#(?=((?:[a-z0-9-._~!$&'()*+,;=:@\\/?]|%[0-9A-F]{2})*))\\12)?$/i", $uri ) )
    {
        throw new \RuntimeException( "URI has not a valid format." );
    }
    

    I have successfully unit-tested this function inside a ValueObject I made named Uri and tested by UriTest.

    UriTest.php (Contains valid and invalid cases for both URLs and URNs)

    assertInstanceOf( 'XaviMontero\\ThrasherPortage\\Tour\\Uri', $sut );
        }
    
        /**
         * @dataProvider urlIsValidProvider
         * @dataProvider urnIsValidProvider
         */
        public function testGetUriAsStringWhenUriIsValid( string $uri )
        {
            $sut = new Uri( $uri );
            $actual = $sut->getUriAsString();
    
            $this->assertInternalType( 'string', $actual );
            $this->assertEquals( $uri, $actual );
        }
    
        public function urlIsValidProvider()
        {
            return
                [
                    [ 'http://example-server' ],
                    [ 'http://example.com' ],
                    [ 'http://example.com/' ],
                    [ 'http://subdomain.example.com/path/?parameter1=value1¶meter2=value2' ],
                    [ 'random-protocol://example.com' ],
                    [ 'http://example.com:80' ],
                    [ 'http://example.com?no-path-separator' ],
                    [ 'http://example.com/pa%20th/' ],
                    [ 'ftp://example.org/resource.txt' ],
                    [ 'file://../../../relative/path/needs/protocol/resource.txt' ],
                    [ 'http://example.com/#one-fragment' ],
                    [ 'http://example.edu:8080#one-fragment' ],
                ];
        }
    
        public function urnIsValidProvider()
        {
            return
                [
                    [ 'urn:isbn:0-486-27557-4' ],
                    [ 'urn:example:mammal:monotreme:echidna' ],
                    [ 'urn:mpeg:mpeg7:schema:2001' ],
                    [ 'urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66' ],
                    [ 'rare-urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66' ],
                    [ 'urn:FOO:a123,456' ]
                ];
        }
    
        /**
         * @dataProvider urlIsNotValidProvider
         * @dataProvider urnIsNotValidProvider
         */
        public function testCreationThrowsExceptionWhenUriIsNotValid( string $uri )
        {
            $this->expectException( 'RuntimeException' );
            $this->sut = new Uri( $uri );
        }
    
        public function urlIsNotValidProvider()
        {
            return
                [
                    [ 'only-text' ],
                    [ 'http//missing.colon.example.com/path/?parameter1=value1¶meter2=value2' ],
                    [ 'missing.protocol.example.com/path/' ],
                    [ 'http://example.com\\bad-separator' ],
                    [ 'http://example.com|bad-separator' ],
                    [ 'ht tp://example.com' ],
                    [ 'http://exampl e.com' ],
                    [ 'http://example.com/pa th/' ],
                    [ '../../../relative/path/needs/protocol/resource.txt' ],
                    [ 'http://example.com/#two-fragments#not-allowed' ],
                    [ 'http://example.edu:portMustBeANumber#one-fragment' ],
                ];
        }
    
        public function urnIsNotValidProvider()
        {
            return
                [
                    [ 'urn:mpeg:mpeg7:sch ema:2001' ],
                    [ 'urn|mpeg:mpeg7:schema:2001' ],
                    [ 'urn?mpeg:mpeg7:schema:2001' ],
                    [ 'urn%mpeg:mpeg7:schema:2001' ],
                    [ 'urn#mpeg:mpeg7:schema:2001' ],
                ];
        }
    }
    

    Uri.php (Value Object)

    assertUriIsCorrect( $uri );
            $this->uri = $uri;
        }
    
        public function getUriAsString()
        {
            return $this->uri;
        }
    
        private function assertUriIsCorrect( string $uri )
        {
            // https://stackoverflow.com/questions/30847/regex-to-validate-uris
            // http://snipplr.com/view/6889/regular-expressions-for-uri-validationparsing/
    
            if( ! preg_match( "/^([a-z][a-z0-9+.-]*):(?:\\/\\/((?:(?=((?:[a-z0-9-._~!$&'()*+,;=:]|%[0-9A-F]{2})*))(\\3)@)?(?=(\\[[0-9A-F:.]{2,}\\]|(?:[a-z0-9-._~!$&'()*+,;=]|%[0-9A-F]{2})*))\\5(?::(?=(\\d*))\\6)?)(\\/(?=((?:[a-z0-9-._~!$&'()*+,;=:@\\/]|%[0-9A-F]{2})*))\\8)?|(\\/?(?!\\/)(?=((?:[a-z0-9-._~!$&'()*+,;=:@\\/]|%[0-9A-F]{2})*))\\10)?)(?:\\?(?=((?:[a-z0-9-._~!$&'()*+,;=:@\\/?]|%[0-9A-F]{2})*))\\11)?(?:#(?=((?:[a-z0-9-._~!$&'()*+,;=:@\\/?]|%[0-9A-F]{2})*))\\12)?$/i", $uri ) )
            {
                throw new \RuntimeException( "URI has not a valid format." );
            }
        }
    }
    

    Running UnitTests

    There are 65 assertions in 46 tests. Caution: there are 2 data-providers for valid and 2 more for invalid expressions. One is for URLs and the other for URNs. If you are using a version of PhpUnit of v5.6* or earlier then you need to join the two data providers into a single one.

    xavi@bromo:~/custom_www/hello-trip/mutant-migrant$ vendor/bin/phpunit
    PHPUnit 5.7.3 by Sebastian Bergmann and contributors.
    
    ..............................................                    46 / 46 (100%)
    
    Time: 82 ms, Memory: 4.00MB
    
    OK (46 tests, 65 assertions)
    

    Code coverage

    There's is 100% of code-coverage in this sample URI checker.

提交回复
热议问题