Last active
February 21, 2025 10:29
-
-
Save rmpel/6b86ab8b8ba74856799f4e8e71002cd9 to your computer and use it in GitHub Desktop.
Is your LocalWP crashing (service unavailable) when using dns_get_record? Try this;
This file contains hidden or 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
<?php | |
/** | |
* @file: a polyfill that replaces the stock dns_get_record, use in conjunction with | |
* disable_functions = dns_get_record | |
* in php.ini.hbs . | |
*/ | |
// PHP 7 ignores the disable_functions directive. | |
if ( ! function_exists( 'dns_get_record' ) && version_compare( phpversion(), '8', '>=' ) ) { | |
/** | |
* A version of dns_get_record that does NOT crash on local, and is more secure as it uses DNS over HTTPS via Cloudflare. | |
* @param string $hostname the hostname to lookup. | |
* @param int $type the record type to lookup. Uses the PHP Default DNS_* constants, see \dns_get_record(). | |
*/ | |
function dns_get_record( $hostname, $type = DNS_ANY ) { | |
$php_to_cf_type = [ | |
DNS_A => 'A', | |
DNS_AAAA => 'AAAA', | |
DNS_CNAME => 'CNAME', | |
DNS_MX => 'MX', | |
DNS_NS => 'NS', | |
DNS_PTR => 'PTR', | |
DNS_SOA => 'SOA', | |
DNS_TXT => 'TXT', | |
]; | |
$cf_numeric_types = [ | |
1 => 'A', | |
2 => 'NS', | |
5 => 'CNAME', | |
6 => 'SOA', | |
12 => 'PTR', | |
15 => 'MX', | |
16 => 'TXT', | |
28 => 'AAAA', | |
]; | |
$cf_type = $php_to_cf_type[ $type ] ?? 'ANY'; | |
$ch = curl_init(); | |
curl_setopt( $ch, CURLOPT_URL, 'https://cloudflare-dns.com/dns-query?name=' . $hostname . '&type=' . $cf_type ); | |
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); | |
curl_setopt( $ch, CURLOPT_TIMEOUT, 5 ); | |
curl_setopt( $ch, CURLOPT_HTTPHEADER, [ | |
'accept: application/dns-json', | |
'referer: https://cloudflare-dns.com/dns-query', | |
] ); | |
$result = curl_exec( $ch ); | |
if ( curl_errno( $ch ) ) { | |
curl_close( $ch ); | |
return []; | |
} | |
curl_close( $ch ); | |
if ( ! $result ) { | |
return []; | |
} | |
$result = json_decode( $result, true ); | |
if ( ! $result ) { | |
return []; | |
} | |
$answer = $result['Answer'] ?? []; | |
if ( ! $answer ) { | |
return []; | |
} | |
$return = array(); | |
foreach ( $answer as $entry ) { | |
$entry = array_change_key_case( $entry, CASE_LOWER ); | |
$return_type = $entry['type'] ?? 0; | |
$request_type = $php_to_cf_type[ $type ] ?? 'UNKNOWN'; | |
$return_type = $cf_numeric_types[ $return_type ] ?? $request_type; | |
$entry['type'] = $return_type; | |
$entry['ttl'] = $entry['TTL'] ?? 0; | |
$entry['class'] = $entry['class'] ?? 'IN'; | |
$entry['host'] = $entry['name'] ?? $hostname; | |
$ip = $entry['data'] ?? ''; | |
if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) { | |
$entry['ipv6'] = $ip; | |
} else { | |
$entry['ip'] = $ip; | |
} | |
$entry[ strtolower( $return_type ) ] = trim( $entry['data'] ?? '', '" ' ); | |
$return[] = $entry; | |
} | |
return $return; | |
} | |
} | |
# Require the file that LocalWP uses with `auto_prepend_file`. Adjust for Linux/Windows by checking a php.ini | |
# file you already have on your system. | |
require_once( '/Applications/Local.app/Contents/Resources/extraResources/local-bootstrap.php' ); |
This file contains hidden or 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
# changes-to--php.ini.hbs | |
... | |
disable_functions = dns_get_record | |
... | |
auto_prepend_file = /path/to/the/dns_get_record_polyfill.php | |
... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Please note; this does NOT work with php 7.
PHP 8 truly removes the
dns_get_record
function from memory (or rather, doesn't load it) when disabled.PHP 7 only prevents execution.
Thus, the code is adjusted to not function on php 7. You will get errors when trying to access dns_get_record, but at least it will no longer crash without telling you why ;)