PHPackages                             mindtouch/mindtouch-http - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. mindtouch/mindtouch-http

ActiveLibrary[API Development](/categories/api)

mindtouch/mindtouch-http
========================

A PHP library for interacting with the MindTouch REST API

3.1.3(5y ago)363.4k↓32.7%4Apache-2.0PHPPHP ^7.2.0CI failing

Since Apr 9Pushed 3y ago21 watchersCompare

[ Source](https://github.com/MindTouch/mindtouch-http.php)[ Packagist](https://packagist.org/packages/mindtouch/mindtouch-http)[ RSS](/packages/mindtouch-mindtouch-http/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (5)Versions (34)Used By (0)

MindTouch HTTP
==============

[](#mindtouch-http)

A PHP library for interacting with the [MindTouch API](https://success.mindtouch.com/Integrations/API).

[![github.com](https://github.com/MindTouch/mindtouch-http.php/workflows/build/badge.svg)](https://github.com/MindTouch/mindtouch-http.php/actions?query=workflow%3Abuild)[![codecov.io](https://camo.githubusercontent.com/17127b59c85c8882dbd908aa3df4d16f29b0d14d59b8510fd08fb4f12e1841fa/68747470733a2f2f636f6465636f762e696f2f6769746875622f4d696e64546f7563682f6d696e64746f7563682d687474702e7068702f636f7665726167652e7376673f6272616e63683d6d61696e)](https://codecov.io/github/MindTouch/mindtouch-http.php?branch=main)[![Latest Stable Version](https://camo.githubusercontent.com/4bbaceaa0deaee718610869e3be5b6e4c021d017e9387303cfdd0b4c39828522/68747470733a2f2f706f7365722e707567782e6f72672f6d696e64746f7563682f6d696e64746f7563682d687474702f76657273696f6e2e737667)](https://packagist.org/packages/mindtouch/mindtouch-http)[![Latest Unstable Version](https://camo.githubusercontent.com/a62d3074fe06f3f300bee8ddc44cf76d478923bf6da91539bcefb4e77af8edc9/68747470733a2f2f706f7365722e707567782e6f72672f6d696e64746f7563682f6d696e64746f7563682d687474702f762f756e737461626c65)](https://packagist.org/packages/mindtouch/mindtouch-http)[![Total Downloads](https://camo.githubusercontent.com/51e76d17e8852020fa294d872b3d33499c95272fa0c43246dc05c7250801a133/68747470733a2f2f706f7365722e707567782e6f72672f6d696e64746f7563682f6d696e64746f7563682d687474702f646f776e6c6f616473)](//packagist.org/packages/mindtouch/mindtouch-http)

Support
-------

[](#support)

This library is provided for and supported by the open source community. Supported [MindTouch](https://mindtouch.com) site owners may file bug reports via [GitHub](https://github.com/MindTouch/mindtouch-http.php/issues), but support plans do not cover the usage of this library.

Requirements
------------

[](#requirements)

- PHP 5.5, 5.6 (1.x)
- PHP 7.2, 7.3, 7.4 (main, 2.x, 3.x)

Installation
------------

[](#installation)

Use [Composer](https://getcomposer.org/). There are two ways to add this library to your project.

From the composer CLI:

```
./composer.phar require mindtouch/mindtouch-http
```

Or add mindtouch/mindtouch-http to your project's composer.json:

```
{
    "require": {
        "mindtouch/mindtouch-http": "dev-main"
    }
}
```

`dev-main` is the main development branch. If you are using this library in a production environment, it is advised that you use a stable release.

Assuming you have setup Composer's autoloader, the library can be found in the `MindTouch\Http\` namespace.

Getting Started
---------------

[](#getting-started)

A quick example:

```
$plug = new ApiPlug(XUri::newFromString('https://mindtouch.example.com/@api/deki'));
$result = $plug->at('pages', 'home', 'contents')->get();
if($result->isSuccess()) {

    // great job!
    echo $result->getVal('body/contents');
}
```

Common Scenarios
----------------

[](#common-scenarios)

### Access a Page and Contents

[](#access-a-page-and-contents)

```
$plug = new ApiPlug(XUri::newFromString('https://mindtouch.example.com/@api/deki'));
$pagesPlug = $plug->at('pages')->with('include', 'contents');

// request page id 7239 with contents
$result = $pagesPlug->at('7239')->get();

// extract page content body
$content = $result->getVal('body/page/contents/body');
```

### List all Tags

[](#list-all-tags)

```
$plug = new ApiPlug(XUri::newFromString('https://mindtouch.example.com/@api/deki'));

// request all site tags
$result = $plug->at('site', 'tags')->get();

// extract tags
$tags = $result->getAll('body/tags/tag');
```

### List Pages with a Tag

[](#list-pages-with-a-tag)

```
$plug = new ApiPlug(XUri::newFromString('https://mindtouch.example.com/@api/deki'));
$tagsPlug = $plug->at('site', 'tags');

// request all pages that are tagged "access"
$result = $plug->at('=access')->get();

// extract pages
$pages = $result->getAll('body/tag/page');
```

### List Page SubPages

[](#list-page-subpages)

```
$plug = new ApiPlug(XUri::newFromString('https://mindtouch.example.com/@api/deki'));
$pagesPlug = $plug->at('pages');

// request all immediate subpages of page id 7795
$result = $pagesPlug->at('7795', 'subpages')->get();

// extract subpages
$pages = $result->getAll('body/subpages/page.subpage');
```

### List Page Files

[](#list-page-files)

```
$plug = new ApiPlug(XUri::newFromString('https://mindtouch.example.com/@api/deki'));
$pagesPlug = $plug->at('pages');

// request a list of all files attached to page path 'lorem/ipsum/dolor'
$result = $pagesPlug->at('=lorem/ipsum/dolor', 'files')->get();

// extract list of files
$files = $result->getAll('body/files/file');
```

### List Page Tags

[](#list-page-tags)

```
$plug = new ApiPlug(XUri::newFromString('https://mindtouch.example.com/@api/deki'));
$pagesPlug = $plug->at('pages');

// request a list of all tags on page id 619
$result = $pagesPlug->at('619', 'tags')->get();

// extract list of tags
$tags = [];
foreach($result->getAll('body/tags/tag') as $tag) {
    $tags[] = $tag['@value'];
}
```

Advanced Usage
--------------

[](#advanced-usage)

This library is an extension of [modethirteen/HyperPlug](https://github.com/modethirteen/HyperPlug) and derives most if it's capabilities from it. However, this library's `ApiPlug` class provides specialized behavior for interacting with the MindTouch API.

```
// the library allows for programmatic URL construction and parsing
$uri = XUri::newFromString('http://mindtouch.example.com/@api')

    // every step in a URL builder returns an immutable XUri object
    ->withScheme('https')
    ->at('scim', 'v2', 'users')
    ->withQueryParam('xyzzy', 'plugh')
    ->withQueryParams(QueryParams::newFromArray([
        'bar' => 'qux',
        'baz' => 'fred'
    ]))
    ->withoutQueryParam('bar');

// QueryParams objects are normally immutable
$params = $uri->getQueryParams();

// we can change the data structure of a QueryParams object if we must
$params = $params->toMutableQueryParams();
$params->set('baz', 'abc');

// QueryParams are also iterable
foreach($params as $param => $value) {
    $uri = $uri->withReplacedQueryParam($param, $value);
}

// what does our URL look like now?
$result = $uri->toString(); // https://mindtouch.example.com/@api/scim/v2/users?xyzzy=plugh&baz=abc

// we can give our XUri object to a Plug or an ApiPlug to create a client
$plug = new \modethirteen\Http\Plug($uri);

// Plug holds the main HTTP client functionality which can technically be used with any HTTP server
// ...however ApiPlug provides a layer of MindTouch API-specific request formatting and response handling
// ...and is highly recommended when connecting to the MindTouch API
$plug = new ApiPlug($uri);

// like every object in this library, attaching new values or behaviors to plugs is by default immutable
// ...and returns a new object reference

// add a Server API Token for administrator authorization
// ... which calculates Server API Token hash at HTTP request invocation
$plug->withApiToken((new ApiToken('rabbits', 'hasen'))->withUsername('admin'));

// we can add some additional URL path segements and query parameters that weren't part of the constructing URL
$plug = $plug->at('another', 'additional', 'endpoint', 'segment')->with('more', 'params');

// how many redirects will we follow?
$plug = $plug->withAutoRedirects(2);

// HTTP requests often need HTTP headers
$plug = $plug->withHeader('X-FcStPauli', 'hells')
    ->withAddedHeader('X-FcStPauli', 'bells')
    ->withHeader('X-HSV', 'you\'ll never walk again');

// ...or not
$plug = $plug->withoutHeader('X-HSV');

// the Headers object, like XUri and QueryParams, is normally immutable
$headers = $plug->getHeaders();
$result = $headers->getHeader('X-FcStPauli'); // ['hells', 'bells']
$result = $headers->getHeaderLine('X-FcStPauli'); // X-HSV: hells, bells

// but if you really want to...
$mutableHeaders = $headers->toMutableHeaders();
$mutableHeaders->set('X-HSV', 'keiner mag den hsv');

// a Headers object is iterable
foreach($mutableHeaders as $header => $values) {
    foreach($values as $value) {

        // HTTP headers can have multiple stored values
        // ...though normally sent via an HTTP client as comma separated on a single HTTP header line
        echo "{$header}: {$value}";
    }
}

// also we can merge the two sets of Headers (the original and the mutated one)
// ...to create a brand new object containing the values of both
$mergedHeaders = $headers->toMergedHeaders($mutableHeaders);

// we've built out a pretty complex HTTP client now
// ...but what if we want a client with a different URL but everything else the same?
$alternateApiPlug = $plug->withUri(XUri::newFromString('https://deki.example.com/@api/deki'));

// we are going to invoke an HTTP request
// ...pre and post invocation callbacks can attach special logic and handlers
// ...intended to be executed whenever or wherever this HTTP client is used
// ...maybe there is some logic we want to always perform at the moment the HTTP request is about to be sent?
$plug = $plug->withPreInvokeCallback(function(XUri $uri, IHeaders $headers) {

    // last chance to change the URL or HTTP headers before the request is made
    // ...URL and HTTP headers for the single request invocation can be mutated
    // ...this will not affect the URL or HTTP headers configured in the plug
    $headers->toMutableHeaders()->addHeader('something', 'contextual');
});

// multiple callbacks can be attached (they are executed in the order they are attached)
$plug = $plug->withPreInvokeCallback(function(XUri $uri, IHeaders $headers) {
});

// maybe we want to attach some special handling that always executes when we receive an HTTP response?
$plug = $plug->withPostInvokeCallback(function(HttpResult $result) {

    // perhaps there is special behavior to always trigger based on the HTTP response status code?
    if($result->is(403)) {
    }
});

// HTTP responses can be parsed from text into traversable data structures by attaching one or more HttpResultParser objects
// ...parsing can be possibly memory intensive, so limits can be put on the allowed size of a response to parse
$plug = $plug->withHttpResultParser((new JsonParser())->withMaxContentLength(640000));

// fetching HTTP data is handled via HTTP GET
$result = $plug->get();

// POST or PUT can optionally send data, in a several different content types as needed
$result = $plug->post(
    (new MultiPartFormDataContent([
        'a' => 'b',
        'c' => 'd'
    ]))
    ->withFileContent(new FileContent('/path/to/file'))
);
$result = $plug->put(new FileContent('/path/to/file'));
$result = $plug->post(new UrlEncodedFormDataContent([
    'e' => 'f',
    'g' => 'h'
]));
$result = $plug->post(JsonContent::newFromArray([
    'a' => [
        'multi-dimensional' => [
            'data',
            'structure'
        ]
    ]
]));
$result = $plug->post(XmlContent::newFromArray([
    'another' => [
        'multi-dimensional' => [
            'data',
            'structure'
        ],
        'formatted' => 'as xml'
    ]
]));
$result = $plug->put(new TextContent('good old text!'));

// during the invocation process, an ApiResultException may be raised
// ...such as a max HTTP response content length exceeded or an HTTP response parser failure
// ...exceptions can bubble up to the HTTP client callsite, or handled in the HTTP client internally
$plug = $plug->withResultErrorHandler(function(ApiResultException $e) : bool {
    if($e instanceof HttpResultParserException) {

        // always suppress this exception
        return false;
    }
    return true;
});
```

You are encouraged to explore the library [classes](src) and [tests](tests) to learn more about the capabilities not listed here.

Development and Testing
-----------------------

[](#development-and-testing)

Though the library is sponsored by [MindTouch, Inc.](https://mindtouch.com), contributions are always welcome from the community ([there are defects and enhancements to address](https://github.com/MindTouch/mindtouch-http.php/issues)).

The library is tested through a combination of [PHPUnit](https://github.com/sebastianbergmann/phpunit) and [`MockPlug`](src/Mock) (an interceptor that matches `ApiPlug` invocations and returns mocked responses). Further code quality is checked using [PHPStan](https://github.com/phpstan/phpstan) (PHP Static Analysis Tool).

```
# fork and clone the mindtouch-http.php repository
git clone git@github.com:{username}/mindtouch-http.php.git

# install dependencies
composer install

# run static analysis checks
vendor/bin/phpstan analyse --level 7 src

# run tests
vendor/bin/phpunit --configuration phpunit.xml.dist
```

Learn More
----------

[](#learn-more)

- [MindTouch API Documentation](https://success.mindtouch.com/Integrations/API)

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity34

Limited adoption so far

Community18

Small or concentrated contributor base

Maturity69

Established project with proven stability

 Bus Factor1

Top contributor holds 94.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~60 days

Recently: every ~28 days

Total

31

Last Release

1866d ago

Major Versions

0.4.1 → 1.0.02018-05-09

1.2.0 → 2.0.02019-01-23

2.3.3 → 3.0.02020-11-25

PHP version history (4 changes)0.3.0PHP &gt;=5.4.0

1.0.0PHP &gt;=5.5.0

2.0.0PHP &gt;=7.2.0

3.1.1PHP ^7.2.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/3e75ba33e4e92cb2796f90060f5cc18353b469a26f81d2699b9501637d55f37a?d=identicon)[petee](/maintainers/petee)

---

Top Contributors

[![modethirteen](https://avatars.githubusercontent.com/u/45862?v=4)](https://github.com/modethirteen "modethirteen (91 commits)")[![yurigorokhov](https://avatars.githubusercontent.com/u/599374?v=4)](https://github.com/yurigorokhov "yurigorokhov (3 commits)")[![apatten](https://avatars.githubusercontent.com/u/26947?v=4)](https://github.com/apatten "apatten (1 commits)")[![derekrobbins](https://avatars.githubusercontent.com/u/1109174?v=4)](https://github.com/derekrobbins "derekrobbins (1 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/mindtouch-mindtouch-http/health.svg)

```
[![Health](https://phpackages.com/badges/mindtouch-mindtouch-http/health.svg)](https://phpackages.com/packages/mindtouch-mindtouch-http)
```

###  Alternatives

[stripe/stripe-php

Stripe PHP Library

4.0k143.3M480](/packages/stripe-stripe-php)[twilio/sdk

A PHP wrapper for Twilio's API

1.6k92.9M272](/packages/twilio-sdk)[facebook/php-business-sdk

PHP SDK for Facebook Business

90821.9M34](/packages/facebook-php-business-sdk)[meilisearch/meilisearch-php

PHP wrapper for the Meilisearch API

74513.7M114](/packages/meilisearch-meilisearch-php)[google/gax

Google API Core for PHP

265103.1M454](/packages/google-gax)[google/common-protos

Google API Common Protos for PHP

173103.7M50](/packages/google-common-protos)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
