Imagine an online store receiving price lists from 20 suppliers in CSV, XML, and HTML formats. Manually updating 50,000 items daily leads to inevitable errors and duplicates causing lost sales. We solve this – we develop a parser in PHP embedded in 1C-Bitrix, which automatically fetches data from any source and loads it into information blocks. A PHP parser for Bitrix is 2x faster than a Python solution due to direct API access. Contact us – we'll assess the task within one business day.
Over five years, we have implemented more than 20 parsing projects for Bitrix. Each parser is designed for a specific task: whether loading 10,000 products from CSV or gathering data from a dozen competitor websites. We use PHP because it's the native language for Bitrix. The parser can work directly with the information block API, without REST or intermediate queues. This reduces complexity and accelerates development by 2–3 times compared to hybrid setups. For tasks that don't require JavaScript rendering, PHP is the best choice.
Architecture of a PHP Parser
The parser consists of four components:
-
Source configuration. An array or database table with parameters for each source: URL, type (RSS, HTML, API), CSS selectors for data extraction, field mapping, update frequency.
-
HTTP client. For simple tasks – cURL via
CHttpClientfrom Bitrix core or nativecurl_multifor parallel requests. For complex tasks – Guzzle with middleware for retry, logging, proxy rotation. More on parallel requests in the PHP documentation. -
HTML/XML parser.
DOMDocument+DOMXPathfor precise DOM navigation. For CSS selectors – theSymfony\Component\DomCrawlerlibrary. For RSS –SimpleXMLElement. -
Importer. A layer for writing data to Bitrix information blocks via D7 API or the old API (
CIBlockElement).
How to Speed Up Parsing by 10x?
The main bottleneck of a PHP parser is sequential requests. Loading 1,000 pages at 2 seconds each = 33 minutes. With curl_multi, you can handle 10–20 requests in parallel:
$multiHandle = curl_multi_init();
$handles = [];
foreach ($urls as $i => $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_multi_add_handle($multiHandle, $ch);
$handles[$i] = $ch;
}
do {
$status = curl_multi_exec($multiHandle, $active);
curl_multi_select($multiHandle);
} while ($active > 0);
Limitation: more than 50 parallel connections – and PHP starts consuming too much memory. For large-scale parsing (10,000+ URLs), split into batches of 20–30 connections.
Integration with the Bitrix Core
The advantage of a PHP parser is direct API access. No REST, no intermediate database needed. Import into information blocks:
$element = new CIBlockElement();
$elementId = $element->Add([
'IBLOCK_ID' => IBLOCK_CATALOG,
'NAME' => $parsedData['title'],
'XML_ID' => $parsedData['external_id'],
'ACTIVE' => 'Y',
'PREVIEW_TEXT' => $parsedData['description'],
'DETAIL_TEXT' => $parsedData['content'],
'DETAIL_TEXT_TYPE' => 'html',
'PREVIEW_PICTURE' => CFile::MakeFileArray($parsedData['image_path']),
]);
if ($elementId) {
CIBlockElement::SetPropertyValuesEx($elementId, IBLOCK_CATALOG, [
'SOURCE_URL' => $parsedData['url'],
'ARTICLE' => $parsedData['sku'],
]);
}
Important: during mass import, disable search and URL update:
CIBlockElement::DisableEvents(); // Disables event handlers
Without this, each Add() triggers search reindexing, facet index updates, and other handlers – importing 10,000 products would take hours.
Learn more about working with events.
Error Handling and Resilience
A PHP parser in production must handle:
- Timeouts – server not responding, connection hangs. Set
CURLOPT_TIMEOUTandCURLOPT_CONNECTTIMEOUT. - HTTP errors – 403, 429, 503. For 429 (rate limit) – increase delay. For 403 – change proxy. For 503 – retry later.
- Invalid HTML –
DOMDocument::loadHTMLgenerates warnings. Suppress with@orlibxml_use_internal_errors(true), but log problematic URLs. - Memory exhaustion – large HTML pages (5+ MB) consume memory. Set
memory_limitappropriately and free DOM after processing:unset($dom).
Retry pattern with exponential backoff:
function fetchWithRetry(string $url, int $maxRetries = 3): ?string
{
for ($i = 0; $i < $maxRetries; $i++) {
$response = @file_get_contents($url);
if ($response !== false) {
return $response;
}
sleep(pow(2, $i)); // 1, 2, 4 seconds
}
return null;
}
Common errors and handling strategies
| Error Type | Strategy |
|---|---|
| Connection timeout | Retry after 5 seconds, up to 3 attempts |
| HTTP 429 (Too Many Requests) | Increase delay between requests, use proxies |
| HTTP 403 (Forbidden) | Change User-Agent, proxy, authentication |
| HTTP 503 (Service Unavailable) | Retry with exponential backoff |
| Invalid HTML | Activate libxml_use_internal_errors, log URL |
| memory_limit exceeded | Split into batches, free DOM |
Logging
Without logs, debugging a parser is impossible. Minimal set of events to record:
- Start and end of parsing session (time, number of processed URLs).
- Each HTTP request: URL, response status, load time.
- Parsing errors: URL, error type, context.
- Import result: created, updated, skipped (duplicates), errors.
Use \Bitrix\Main\Diag\Logger from D7 or write to a separate parser_log table.
Comparison: PHP vs Python for Parsing
| Criterion | PHP Parser | Python Parser |
|---|---|---|
| Integration with Bitrix | Direct API call (no REST) | Via REST – 20-30% slower |
| JS rendering | No (HTML only) | Yes (Puppeteer, Playwright) |
| Maximum volume per session | up to 50,000 pages | up to 500,000 (async) |
| Development speed from scratch | 5-10 days | 7-14 days (two systems combined) |
When PHP is Not Enough
A PHP parser is not suitable when:
- JavaScript rendering is needed – SPA websites, dynamic content loading. Here a headless browser (Puppeteer/Playwright) is required, which means Node.js or Python.
- Parsing volume exceeds 50,000 pages per session – PHP hits limits with single-threading and memory consumption.
- Complex text processing (NLP, classification, entity extraction) is required – Python's ecosystem is much richer.
In these cases, consider a hybrid approach: Python/Node.js for data collection, PHP for import into Bitrix.
Parser Development Stages
- Source analysis – determine data structure, format, update frequency.
- Architecture design – choose parsing scheme, parallelization, error handling strategy.
- Implementation – write PHP code, integrate with information blocks and external systems.
- Testing – load testing with real data, simulate failures.
- Documentation and handover – architecture description, operation manual, developer training.
What You Get
- A working parser embedded in your 1C-Bitrix instance.
- Full documentation and code comments.
- A 3-month warranty on parser performance after project delivery.
- Free post-project support.
Developing a PHP parser costs 2 times less than a hybrid Python+Node.js solution, and maintenance is 3 times cheaper because all logic resides in one system.
Order parser development – we guarantee results and full documentation. Get a free engineer consultation.







