Our User-Agent parser for PHP supports Device Detection, browser detection, mobile detection, and crawler detection on-premise or in the cloud. IP Intelligence adds IP geolocation, including IP to country data.
It reads User-Agent and User-Agent Client Hints, HTTP request headers that carry browser and device information. For cloud bot detection, Human Confidence reports confidence that a person is viewing the page.
Install the development workspace below. The directory map explains the separate Composer packages and mirrors.
git clone --recurse-submodules https://github.com/51Degrees/51degrees-php.git
cd 51degrees-php
composer installTry the User-Agent tester and IP tester. For cloud use, create a Resource Key.
Created from pipeline-php-core, pipeline-php-engines, pipeline-php-cloudrequestengine, pipeline-php-did, device-detection-php, device-detection-php-onpremise, and location-php, this repository continues their work.
The folder table and product guides below show where to find usage examples and how to build and test the source.
Our PHP packages use the Pipeline API, which combines data services in one processing flow. The packages are grouped by product: pipeline,
device-detection, location and ip-intelligence. Each package keeps its
own composer.json, readme.md and license, and is still published to
Composer as a separate package.
| Directory | Composer package | Packagist mirror | What it is |
|---|---|---|---|
| pipeline/core | 51degrees/fiftyone.pipeline.core |
pipeline-php-core | Core library for the 51Degrees Pipeline API. |
| pipeline/engines | 51degrees/fiftyone.pipeline.engines |
pipeline-php-engines | Engines shared functionality library for 51Degrees Pipeline API. |
| pipeline/cloudrequestengine | 51degrees/fiftyone.pipeline.cloudrequestengine |
pipeline-php-cloudrequestengine | Cloud request engine for 51Degrees Pipeline API. Used to send requests to the 51Degrees cloud service. |
| pipeline/did | 51degrees/fiftyone.pipeline.did |
pipeline-php-did | Strongly typed reader for the 51Did (51Degrees Identifier) returned by the 51Degrees Cloud service, and a client for the cloud's 51Did endpoints. |
| pipeline/translation | 51degrees/fiftyone.pipeline.translation |
None | Generic translation engine for the 51Degrees Pipeline API. |
| device-detection/cloud | 51degrees/fiftyone.devicedetection |
device-detection-php | Device detection engines for the 51Degrees Pipeline API. Identify devices, operating systems, browsers, and crawlers from HTTP headers. |
| device-detection/onpremise | 51degrees/fiftyone.devicedetection |
None | On-premise Device Detection engines for PHP built for the 51Degrees Pipeline API. Parse HTTP headers locally. |
| location | 51degrees/fiftyone.geolocation |
location-php | Geolocation engines for 51Degrees Pipeline API. Perform reverse geocoding using longitude and latitude to populate postal addresses. |
| ip-intelligence | 51degrees/fiftyone.ipintelligence |
None yet | IP Intelligence engines for the 51Degrees Pipeline API. Identify the country, region, network and approximate location of an IP address, via the cloud service or on-premise with a local data file. |
device-detection/onpremise uses the same package name as
device-detection/cloud. It is not on Packagist. Projects use it through a
Composer path repository.
| Path | Contents |
|---|---|
| The package directories above | One Composer package each, published to its mirror as it is |
cxx |
Submodule of 51degrees-cxx, with the C and C++ code, and the data repository as its data submodule |
pipeline/did/owid-php |
Submodule of owid-php, the OWID library pipeline/did uses |
ci |
The scripts the shared 51Degrees CI workflows call |
.github/workflows |
The CI workflows, and the ones that keep the mirrors up to date |
composer.json |
The development install for the whole repository. It is never published |
The require sections of the package composer.json files give this order:
pipeline/corehas no 51Degrees dependency.pipeline/enginesrequires core.pipeline/cloudrequestenginerequires core and engines.device-detection/cloud,locationandip-intelligencerequire core, engines and cloudrequestengine.ip-intelligencealso requires translation.pipeline/translationanddevice-detection/onpremiserequire core and engines.pipeline/didrequires no other 51Degrees package. It requires the OWID library from theowid-phpsubmodule.
The repository has one version, tagged as a plain version such as 4.5.203.
Every package is released together with that number, including a package
that did not change. ci/get-next-package-version.ps1 moves only the patch
number.
Packagist does not read this repository. It reads the old repositories, which
are now read-only mirrors. The mirror of each directory is in the table above
and in ci/packages.ps1.
- On every push to
main,mirror.ymlrunsgit subtree splitfor each mirrored directory and pushes the result to themainbranch of its mirror. - The nightly publish tags
mainhere with the next version. - That tag starts
mirror.ymlagain, which puts the same tag on the split of each directory, on its mirror.pipeline/didgets a commit thatdid-publish.ymlassembles instead, with the OWID source copied in, because Packagist serves an archive of the tag and an archive has no submodules. - Packagist sees the tag on each mirror and makes the release, as it did before the merge.
A version tag must be on main and above every version on the mirrors, or
the workflows refuse it and tag nothing.
pipeline/translation, device-detection/onpremise and
ip-intelligence have no mirror, so they are not released to Packagist
from here.
git clone --recurse-submodules https://github.com/51Degrees/51degrees-php.git
cd 51degrees-php
composer installThe root composer.json uses Composer path repositories. Each 51Degrees
package resolves to its directory in this repository, not to a copy from
Packagist. A change in pipeline/core is seen at once by every package
that uses it.
The free data files go in cxx/data, which is the
data repository. Each one is listed there
as a <file>.link holding the address the file is downloaded from, and the
repository's scripts save the file beside its link. From the root of the
repository, download the Device Detection and IP Intelligence Lite files with
sh cxx/data/get-data-files.sh 51Degrees-LiteV4.1.hash 51Degrees-LiteV41.ipior with cxx/data/get-data-files.ps1 and the same names in PowerShell. With
no names, the scripts download every file. The IP Intelligence examples
download the Lite file themselves when they find no data file.
Git leaves the folder of a removed submodule on disk. When cxx no longer
includes its old device-detection-data and ip-intelligence-data
submodules, delete those two folders from cxx in an existing clone.
Run the unit tests of one package with the root autoloader:
cd pipeline/core
../../vendor/bin/phpunit --bootstrap ../../vendor/autoload.php --testsuite Unitlocation and ip-intelligence sit one level higher, so there the root
vendor is ../vendor.
Each package's phpunit.xml names its test suites. Some packages differ:
locationhas only anIntegrationsuite.pipeline/translationhas aTranslationsuite and notestsdirectory.device-detection/onpremiseis not in the rootcomposer.json. The root autoloader maps its namespace todevice-detection/cloud.
The tests that use the cloud need a Resource Key. See each package's readme for the keys and data files its tests use.
device-detection/onpremise and ip-intelligence each build a PHP
extension from the C code in cxx/src. Each package's ci/build-project.ps1
copies cxx/src into its on-premise/cxx folder before phpize, because PHP
names each object after the path of its source and the two extensions build
the shared code differently. By hand:
cd device-detection/onpremise/on-premise
rm -rf cxx && mkdir cxx && cp -R ../../../cxx/src cxx/src
phpize
./configure
makeThe package readme lists the build requirements and how to install the extension.
The workflows in .github/workflows call the shared workflows in
common-ci, which run the scripts in
ci/ once for the whole repository, on one build matrix from
ci/options.json. Most of those scripts run the script of the same name in
each package's own ci/ folder. ci/packages.ps1 lists the packages and how
each is built and tested.
Open issues and pull requests in this repository only. Do not open them on the mirrors.
Pull requests go to the rc branch, not main. When a release is wanted, one
pull request merges rc into main.
Do not edit a package's composer.json or ci/ directory to make the
monorepo work. CI publishes each package directory to its mirror as it is.
Put monorepo glue in root files only, for example the root composer.json.
The PHP repositories listed below continue as package mirrors where shown in the directory map.
| Earlier repository | What it held |
|---|---|
| pipeline-php-core | The Pipeline API core |
| pipeline-php-engines | Pipeline engines |
| pipeline-php-cloudrequestengine | The cloud request engine |
| pipeline-php-did | 51Did |
| device-detection-php | Device Detection |
| device-detection-php-onpremise | On-premise Device Detection |
| location-php | Location |
The old repositories were brought in with git subtree add, without
--squash, so commit SHAs match the originals. Use git log --follow to trace
a file back through the import.
The packages are licensed under the European Union Public Licence 1.2
(EUPL-1.2). Each package directory has its own LICENSE file.
