-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from hostinger/feat/update-php-dig
feat: Partially refactor and update php-dig to PHP8
- Loading branch information
Showing
26 changed files
with
510 additions
and
384 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,16 +6,28 @@ | |
It should drastically decrease time to get dns records, and lower failure errors like `dns_get_record(): A temporary server error occurred.` | ||
|
||
## Installation | ||
Install the latest version with | ||
|
||
For now this package is not on [Packgist](https://packagist.org/), so you need to add it to your composer.json manually | ||
```json | ||
{ | ||
"repositories": [ | ||
{ | ||
"type": "vcs", | ||
"url": "[email protected]:hostinger/php-dig.git" | ||
} | ||
] | ||
} | ||
``` | ||
|
||
Install the latest version with | ||
```console | ||
$ composer require hostinger/php-dig | ||
``` | ||
|
||
## Usage | ||
|
||
```php | ||
$client = new Hostinger\DigClient(); | ||
$client = new \Hostinger\Dig\Client(); | ||
$result = $client->getRecord('hostinger.com', DNS_MX); | ||
``` | ||
|
||
|
@@ -28,8 +40,9 @@ Package checks if it can run `exec` in server environment, otherwise it will fal | |
|
||
### DigClient implements LoggerAwareInterface | ||
You can set [logger](https://github.com/Seldaek/monolog/) to debug / log package activity | ||
|
||
```php | ||
$client = new Hostinger\DigClient(); | ||
$client = new \Hostinger\Dig\Client(); | ||
$logger = new \Monolog\Logger\Logger('App'); | ||
$logger->pushHandler(new StreamHandler('path/to/your.log')); | ||
$client->setLogger($logger); | ||
|
@@ -39,7 +52,7 @@ $client->setLogger($logger); | |
|
||
### Requirements | ||
|
||
- php-dig client works with PHP 5.6 or above. | ||
- php-dig client works with PHP 8.0 or above. | ||
|
||
### Submitting bugs and feature requests | ||
|
||
|
@@ -48,4 +61,4 @@ Bugs and feature request are tracked on [GitHub](https://github.com/hostinger/ph | |
|
||
## Sources | ||
- [Stack overflow question What would cause checkdnsrr() or dns_get_record() to take too long?](http://stackoverflow.com/questions/14065946/what-would-cause-checkdnsrr-or-dns-get-record-to-take-too-long) | ||
- [Reddit thread: dns_get_record suddenly running very slowly](https://www.reddit.com/r/PHP/comments/2k3ns7/dns_get_record_suddenly_running_very_slowly/) | ||
- [Reddit thread: dns_get_record suddenly running very slowly](https://www.reddit.com/r/PHP/comments/2k3ns7/dns_get_record_suddenly_running_very_slowly/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
parameters: | ||
level: 6 | ||
paths: | ||
- src | ||
- tests |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,8 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<phpunit backupGlobals="false" | ||
backupStaticAttributes="false" | ||
bootstrap="vendor/autoload.php" | ||
colors="true" | ||
convertErrorsToExceptions="true" | ||
convertNoticesToExceptions="true" | ||
convertWarningsToExceptions="true" | ||
processIsolation="false" | ||
stopOnFailure="false"> | ||
<phpunit bootstrap="./tests/bootstrap.php" colors="true"> | ||
<testsuites> | ||
<testsuite> | ||
<directory suffix="Test.php">./tests</directory> | ||
<testsuite name="Hostinger PHP Dig"> | ||
<directory suffix="Test.php">tests/</directory> | ||
</testsuite> | ||
</testsuites> | ||
<filter> | ||
<whitelist processUncoveredFilesFromWhitelist="true"> | ||
<directory suffix=".php">./src</directory> | ||
</whitelist> | ||
</filter> | ||
</phpunit> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Hostinger\Dig; | ||
|
||
use Closure; | ||
use ErrorException; | ||
use Hostinger\Dig\RecordType\RecordType; | ||
use Psr\Log\LoggerAwareInterface; | ||
use Psr\Log\LoggerAwareTrait; | ||
use Psr\Log\NullLogger; | ||
|
||
class Client implements LoggerAwareInterface | ||
{ | ||
use LoggerAwareTrait; | ||
|
||
protected Closure $fallback; | ||
|
||
/** | ||
* @param Closure|null $customFallback Fallback to use when dig fails. Should take two arguments: domain and type. | ||
*/ | ||
public function __construct(Closure $customFallback = null) | ||
{ | ||
$this->logger = new NullLogger(); | ||
$this->fallback = $customFallback ?? Closure::fromCallable([$this, 'defaultFallback']); | ||
} | ||
|
||
/** | ||
* @param Closure $fallback Fallback to use when dig fails. Should take two arguments: domain and type. | ||
*/ | ||
public function setFallback(Closure $fallback): void | ||
{ | ||
$this->fallback = $fallback; | ||
} | ||
|
||
/** | ||
* Resets fallback to default dns_get_record() call. | ||
* @return void | ||
*/ | ||
public function resetFallback(): void | ||
{ | ||
$this->fallback = Closure::fromCallable([$this, 'defaultFallback']); | ||
} | ||
|
||
/** | ||
* @param string $domain | ||
* @param int $type One of the DNS_* constants | ||
* @param string $dnsProvider | ||
* @param int $timeout | ||
* @return array | ||
*/ | ||
public function getRecord(string $domain, int $type, string $dnsProvider = '8.8.8.8', int $timeout = 2): array | ||
{ | ||
$recordTypeFactory = new RecordTypeFactory(); | ||
$recordType = $recordTypeFactory->make($type); | ||
if (is_null($recordType)) { | ||
$this->logger->warning('Unsupported DNS type', [ | ||
'domain' => $domain, | ||
'type' => RecordTypeFactory::dnsTypeToName($type), | ||
]); | ||
return ($this->fallback)($domain, $type); | ||
} | ||
|
||
$execState = $this->execEnabled(); | ||
if ($execState !== true) { | ||
$this->logger->warning('EXEC disabled', [ | ||
'domain' => $domain, | ||
'type' => $recordType->getType(), | ||
'error' => $execState, | ||
]); | ||
return ($this->fallback)($domain, $type); | ||
} | ||
|
||
$this->logger->debug('execute dig', ['domain' => $domain, 'type' => $recordType->getType()]); | ||
|
||
return $this->executeDig($domain, $recordType, $dnsProvider, $timeout); | ||
} | ||
|
||
/** | ||
* Use custom error handler to convert dns_get_record() errors to exceptions. | ||
* It throws a warning when the DNS query fails. | ||
* @see http://stackoverflow.com/a/1241751/2728507 | ||
* @see http://php.net/manual/en/function.restore-error-handler.php | ||
* @param string $domain | ||
* @param int $type | ||
* @return array | ||
* @throws ErrorException | ||
*/ | ||
protected function defaultFallback(string $domain, int $type): array | ||
{ | ||
set_error_handler(function ($errno, $errstr, $errfile, $errline) { | ||
// error was suppressed with the @-operator | ||
if (0 === error_reporting()) { | ||
return false; | ||
} | ||
|
||
throw new ErrorException($errstr, 0, $errno, $errfile, $errline); | ||
}); | ||
|
||
try { | ||
return dns_get_record($domain, $type); | ||
} catch (ErrorException $errorException) { | ||
$this->logger->critical('dns_get_record() query failed', [ | ||
'domain' => $domain, | ||
'type' => RecordTypeFactory::dnsTypeToName($type), | ||
'error' => $errorException->getMessage(), | ||
]); | ||
} finally { | ||
restore_error_handler(); | ||
} | ||
|
||
return []; | ||
} | ||
|
||
/** | ||
* Check if system allowed to execute commands. Return true or string with error message | ||
* @return bool|string | ||
*/ | ||
protected function execEnabled(): bool|string | ||
{ | ||
if (!function_exists('exec')) { | ||
return 'missing_function_exec'; | ||
} | ||
|
||
$disabled = explode(',', ini_get('disable_functions')); | ||
if (in_array('exec', $disabled)) { | ||
return 'disabled_function_exec'; | ||
} | ||
|
||
$lines = []; | ||
$command = 'dig -v 2>&1 | grep "not found" '; | ||
exec($command, $lines); | ||
if (!empty($lines)) { | ||
return 'dig not found'; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
protected function executeDig( | ||
string $domain, | ||
RecordType $recordType, | ||
string $dnsProvider = '8.8.8.8', | ||
int $timeout = 2 | ||
): ?array { | ||
$dnsType = strtoupper($recordType->getType()); | ||
$command = sprintf( | ||
'dig @%s +noall +answer +time=%u %s %s', | ||
escapeshellarg($dnsProvider), | ||
$timeout, | ||
escapeshellarg($dnsType), | ||
escapeshellarg($domain) | ||
); | ||
|
||
exec($command, $output, $returnCode); | ||
if ($returnCode !== 0 || empty($output)) { | ||
return null; | ||
} | ||
|
||
return $recordType->transform($output); | ||
} | ||
} |
Oops, something went wrong.