Home/Blog/Mobile Proxy for PHP
Developer Guide

Mobile Proxy for PHP

PHP's cURL extension routes through a proxy with three options: CURLOPT_PROXY, CURLOPT_PROXYUSERPWD and CURLOPT_PROXYTYPE. Guzzle wraps the same in a single proxy key. This guide wires both to a mobile proxy and rotates the IP.

7 min read·PHP·Last updated: May 2026

Prerequisites

  • PHP 8.0+ with the curl extension enabled (php -m | grep curl).
  • A mobile proxy slot, HTTP/SOCKS5 ports, username, password and API key from mobileproxies.org.
  • For Guzzle: composer require guzzlehttp/guzzle.

Step-by-Step Configuration

STEP 01

Read credentials from the environment

<?php
// config.php — load from env, never hard-code secrets
$MP = [
    'host'      => getenv('MP_HOST')      ?: 'proxy.mobileproxies.org',
    'http_port' => getenv('MP_HTTP_PORT') ?: '8000',
    'socks_port'=> getenv('MP_SOCKS_PORT')?: '1080',
    'user'      => getenv('MP_USER'),
    'pass'      => getenv('MP_PASS'),
    'api_key'   => getenv('MP_API_KEY'),
    'slot'      => getenv('MP_SLOT'),
];
STEP 02

HTTP proxy with cURL

<?php
require 'config.php';

function fetchThroughProxy(string $url, array $mp): string
{
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_PROXY          => "{$mp['host']}:{$mp['http_port']}",
        CURLOPT_PROXYTYPE      => CURLPROXY_HTTP,
        CURLOPT_PROXYUSERPWD   => "{$mp['user']}:{$mp['pass']}",
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_FOLLOWLOCATION => true,
    ]);

    $body = curl_exec($ch);
    if ($body === false) {
        throw new RuntimeException('cURL error: ' . curl_error($ch));
    }
    curl_close($ch);
    return $body;
}
STEP 03

SOCKS5 proxy with cURL

<?php
// Same handle, swap the port and proxy type to SOCKS5.
// CURLPROXY_SOCKS5_HOSTNAME resolves DNS on the proxy side.
curl_setopt($ch, CURLOPT_PROXY, "{$mp['host']}:{$mp['socks_port']}");
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5_HOSTNAME);
curl_setopt($ch, CURLOPT_PROXYUSERPWD, "{$mp['user']}:{$mp['pass']}");
STEP 04

Guzzle client

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

use GuzzleHttp\Client;

// Guzzle accepts a full proxy URL with embedded credentials.
$proxy = sprintf(
    'http://%s:%s@%s:%s',
    rawurlencode($mp['user']),
    rawurlencode($mp['pass']),
    $mp['host'],
    $mp['http_port']
);

$client = new Client([
    'proxy'   => $proxy,   // use "socks5://..." for the SOCKS5 port
    'timeout' => 30,
]);

$response = $client->get('https://example.com');
echo $response->getStatusCode();

Verify It Works

Fetch api.ipify.org through the proxy and print the egress IP. It should be a carrier-owned mobile IP, never your server's real address.

<?php
require 'config.php';

$ip = fetchThroughProxy('https://api.ipify.org', $MP);
echo "Egress IP: {$ip}\n"; // e.g. 100.42.x.x on a mobile ASN

Rotate the IP

Request a fresh carrier IP with a POST to the switch endpoint. This call goes direct (not through the proxy) and authenticates with your API key:

<?php
function rotateProxy(array $mp): bool
{
    $url = "https://buy.mobileproxies.org/api/v1/proxies/{$mp['slot']}/switch";

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_HTTPHEADER     => ["Authorization: Bearer {$mp['api_key']}"],
        CURLOPT_TIMEOUT        => 10,
    ]);

    curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    curl_close($ch);

    sleep(4); // let the new IP bind
    return $code < 300;
}

Troubleshooting

"Received HTTP code 407 from proxy"

Authentication failed. Confirm CURLOPT_PROXYUSERPWD is set to user:pass exactly, and that the username/password came through from the environment (not empty).

SOCKS5 leaks DNS / resolves locally

Use CURLPROXY_SOCKS5_HOSTNAME instead of CURLPROXY_SOCKS5 so DNS is resolved on the proxy side, hiding the target from your local resolver.

SSL certificate problem through the proxy

Keep CURLOPT_SSL_VERIFYPEER on and point CURLOPT_CAINFO at an up-to-date CA bundle. Never disable verification — that is what attackers count on, not proxies.

Related Guides

Run PHP Through Mobile IPs

$5 trial. Drop the cURL options in, point them at a carrier IP, and rotate on the API.