Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Tests

on:
push:
branches: [ master, main ]
pull_request:
branches: [ master, main ]

jobs:
test:
runs-on: ubuntu-latest
permissions:
contents: read
strategy:
fail-fast: false
matrix:
php-version:
- '5.6'
- '7.0'
- '7.1'
- '7.2'
- '7.3'
- '7.4'
- '8.0'
- '8.1'
- '8.2'
- '8.3'
- '8.4'

name: PHP ${{ matrix.php-version }}

steps:
- uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
coverage: none

- name: Install dependencies
run: |
if [ "${{ matrix.php-version }}" = "5.6" ] || [ "${{ matrix.php-version }}" = "7.0" ] || [ "${{ matrix.php-version }}" = "7.1" ]; then
composer require --dev phpunit/phpunit:^5.7 --no-interaction --no-update
elif [ "${{ matrix.php-version }}" = "7.2" ] || [ "${{ matrix.php-version }}" = "7.3" ] || [ "${{ matrix.php-version }}" = "7.4" ]; then
composer require --dev phpunit/phpunit:^8.5 --no-interaction --no-update
elif [ "${{ matrix.php-version }}" = "8.0" ] || [ "${{ matrix.php-version }}" = "8.1" ]; then
composer require --dev phpunit/phpunit:^9.5 --no-interaction --no-update
else
composer require --dev phpunit/phpunit:^10.0 --no-interaction --no-update
fi
composer install --no-interaction --prefer-dist

- name: Run tests
run: vendor/bin/phpunit
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
.idea
build
composer.lock
vendor
vendor/
.phpunit.cache
.phpunit.result.cache
13 changes: 0 additions & 13 deletions .travis.yml

This file was deleted.

3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,8 @@
},
"autoload": {
"files": ["src/http_build_url.php"]
},
"require-dev": {
"phpunit/phpunit": "^5.7 || ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0"
}
}
14 changes: 4 additions & 10 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./tests/bootstrap.php" colors="true">
<phpunit bootstrap="./tests/bootstrap.php"
colors="true"
verbose="true">
<testsuites>
<testsuite>
<testsuite name="default">
<directory>./tests</directory>
</testsuite>
</testsuites>
Expand All @@ -10,12 +12,4 @@
<directory suffix=".php">./src</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-html" target="build/coverage" title="http_build_url()"
charset="UTF-8" yui="true" highlight="true"
lowUpperBound="35" highLowerBound="70"/>
<log type="coverage-clover" target="build/logs/clover.xml"/>
<log type="junit" target="build/logs/junit.xml"
logIncompleteSkipped="false"/>
</logging>
</phpunit>
132 changes: 131 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# http_build_url() for PHP

[![Build Status](https://travis-ci.org/jakeasmith/http_build_url.png)](https://travis-ci.org/jakeasmith/http_build_url)
[![Tests](https://github.com/jakeasmith/http_build_url/actions/workflows/test.yml/badge.svg)](https://github.com/ozh/http_build_url/actions/workflows/test.yml)
[![Code Climate](https://codeclimate.com/github/jakeasmith/http_build_url/badges/gpa.svg)](https://codeclimate.com/github/jakeasmith/http_build_url)
[![Latest Stable Version](https://poser.pugx.org/jakeasmith/http_build_url/v/stable.png)](https://packagist.org/packages/jakeasmith/http_build_url)
[![Total Downloads](https://poser.pugx.org/jakeasmith/http_build_url/downloads.png)](https://packagist.org/packages/jakeasmith/http_build_url)
Expand All @@ -15,6 +15,136 @@ The easiest way to install this library is to use [Composer](https://getcomposer
$ composer require jakeasmith/http_build_url ^1
```

## Usage

The `http_build_url()` function builds a URL from an array of parts or merges two URLs together according to specified flags.

### Basic Examples

#### Building a URL from parts

```php
<?php
require 'vendor/autoload.php';

// Build a simple URL from an array of parts
$url = http_build_url([
'scheme' => 'https',
'host' => 'www.example.com',
'path' => '/path/to/page',
'query' => 'foo=bar'
]);

echo $url; // https://www.example.com/path/to/page?foo=bar
```

#### Merging URL parts

```php
<?php
require 'vendor/autoload.php';

// Start with a base URL and modify specific parts
$base_url = "http://user:pass@www.example.com:8080/pub/index.php?a=b#files";

$new_url = http_build_url($base_url, [
'scheme' => 'https',
'host' => 'secure.example.com',
'path' => '/new/path.php'
]);

echo $new_url; // https://user:pass@secure.example.com:8080/new/path.php?a=b#files
```

### Advanced Examples with Flags

The function accepts various flags to control how URLs are merged and manipulated:

#### Joining paths

```php
<?php
require 'vendor/autoload.php';

// Join paths together instead of replacing
$url = http_build_url(
"http://example.com/foo/bar/",
['path' => 'baz/qux'],
HTTP_URL_JOIN_PATH
);

echo $url; // http://example.com/foo/bar/baz/qux
```

#### Joining query strings

```php
<?php
require 'vendor/autoload.php';

// Merge query parameters instead of replacing
$url = http_build_url(
"http://example.com/page?foo=bar&old=value",
['query' => 'foo=new&extra=param'],
HTTP_URL_JOIN_QUERY
);

echo $url; // http://example.com/page?foo=new&old=value&extra=param
```

#### Stripping URL components

```php
<?php
require 'vendor/autoload.php';

// Remove authentication info and fragment
$url = http_build_url(
"http://user:pass@www.example.com/path#section",
[],
HTTP_URL_STRIP_AUTH | HTTP_URL_STRIP_FRAGMENT
);

echo $url; // http://www.example.com/path
```

#### Complex example combining multiple operations

```php
<?php
require 'vendor/autoload.php';

// Change scheme to FTP, update host and path, merge query, and strip auth & fragment
$url = http_build_url(
"http://user@www.example.com/pub/index.php?a=b#files",
[
'scheme' => 'ftp',
'host' => 'ftp.example.com',
'path' => 'files/current/',
'query' => 'a=c'
],
HTTP_URL_STRIP_AUTH | HTTP_URL_JOIN_PATH | HTTP_URL_JOIN_QUERY | HTTP_URL_STRIP_FRAGMENT
);

echo $url; // ftp://ftp.example.com/pub/files/current/?a=c
```

### Available Flags

- `HTTP_URL_REPLACE` (default) - Replace parts of the first URL with parts from the second
- `HTTP_URL_JOIN_PATH` - Join relative paths instead of replacing
- `HTTP_URL_JOIN_QUERY` - Merge query parameters instead of replacing
- `HTTP_URL_STRIP_USER` - Remove username from URL
- `HTTP_URL_STRIP_PASS` - Remove password from URL
- `HTTP_URL_STRIP_AUTH` - Remove both username and password
- `HTTP_URL_STRIP_PORT` - Remove port from URL
- `HTTP_URL_STRIP_PATH` - Remove path from URL
- `HTTP_URL_STRIP_QUERY` - Remove query string from URL
- `HTTP_URL_STRIP_FRAGMENT` - Remove fragment (hash) from URL
- `HTTP_URL_STRIP_ALL` - Remove all components except scheme and host

Flags can be combined using the bitwise OR operator (`|`).

## License

This project is licensed under the MIT License - see the LICENSE file for details.
17 changes: 12 additions & 5 deletions tests/HttpBuildUrlTest.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
<?php

class HttpBuildUrlTest extends \PHPUnit_Framework_TestCase
// Use the appropriate base class depending on PHPUnit version
if ( class_exists( 'PHPUnit\Framework\TestCase' ) ) {
class HttpBuildUrlTestBase extends \PHPUnit\Framework\TestCase {}
} else {
class HttpBuildUrlTestBase extends \PHPUnit_Framework_TestCase {}
}

class HttpBuildUrlTest extends HttpBuildUrlTestBase
{
private $full_url = "http://user:pass@www.example.com:8080/pub/index.php?a=b#files";

Expand All @@ -26,7 +33,7 @@ public function testExampleOne()
$this->assertSame($expected, $actual);
}

public function trailingSlashProvider()
public static function trailingSlashProvider()
{
return array(
array(
Expand Down Expand Up @@ -180,7 +187,7 @@ public function testBitmasks($constant, $expected)
$this->assertSame($expected, $actual);
}

public function pathProvider()
public static function pathProvider()
{
return array(
array('/donuts/brownies', 'http://user:pass@www.example.com:8080/donuts/brownies?a=b#files'),
Expand All @@ -189,15 +196,15 @@ public function pathProvider()
);
}

public function queryProvider()
public static function queryProvider()
{
return array(
array('a=c', 'http://user:pass@www.example.com:8080/pub/index.php?a=c#files'),
array('d=a', 'http://user:pass@www.example.com:8080/pub/index.php?a=b&d=a#files')
);
}

public function bitmaskProvider()
public static function bitmaskProvider()
{
return array(
array('HTTP_URL_REPLACE', 'http://user:pass@www.example.com:8080/pub/index.php?a=b#files'),
Expand Down
18 changes: 11 additions & 7 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
<?php
require dirname( __DIR__ ) . '/src/http_build_url.php';

// PHPUnit 6 compatibility for previous versions
if ( class_exists( 'PHPUnit\Runner\Version' ) && version_compare( PHPUnit\Runner\Version::id(), '6.0', '>=' ) ) {
class_alias( 'PHPUnit\Framework\Assert', 'PHPUnit_Framework_Assert' );
class_alias( 'PHPUnit\Framework\TestCase', 'PHPUnit_Framework_TestCase' );
class_alias( 'PHPUnit\Framework\Error\Error', 'PHPUnit_Framework_Error' );
class_alias( 'PHPUnit\Framework\Error\Notice', 'PHPUnit_Framework_Error_Notice' );
class_alias( 'PHPUnit\Framework\Error\Warning', 'PHPUnit_Framework_Error_Warning' );
// PHPUnit 6+ uses namespaced classes, create aliases for older PHPUnit versions compatibility
if ( class_exists( 'PHPUnit\Runner\Version' ) ) {
// PHPUnit 6+
if ( ! class_exists( 'PHPUnit_Framework_TestCase' ) ) {
class_alias( 'PHPUnit\Framework\TestCase', 'PHPUnit_Framework_TestCase' );
}
} else {
// PHPUnit 4-5 - ensure forward compatibility classes exist
if ( ! class_exists( 'PHPUnit\Framework\TestCase' ) && class_exists( 'PHPUnit_Framework_TestCase' ) ) {
class_alias( 'PHPUnit_Framework_TestCase', 'PHPUnit\Framework\TestCase' );
}
}

// Past this point, tests will start