Skip to content

Instantly share code, notes, and snippets.

@rmpel
Last active February 21, 2025 10:29
Show Gist options
  • Save rmpel/6b86ab8b8ba74856799f4e8e71002cd9 to your computer and use it in GitHub Desktop.
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;
<?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' );
# changes-to--php.ini.hbs
...
disable_functions = dns_get_record
...
auto_prepend_file = /path/to/the/dns_get_record_polyfill.php
...
@rmpel
Copy link
Author

rmpel commented Feb 21, 2025

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 ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment