我正在尝试使用php动态创建子域,以便每当有人创建用户时,他们也会创建子域。
我似乎找到的所有答案都是一样的,他们只是不起作用。
这是最常建议的代码:
function createDomain($domain) {
// your cPanel username
$cpanel_user = 'username';
$cpanel_pass = 'pass';
$cpanel_skin = 'paper_lantern';
$cpanel_host = 'mydomainname.com';
$subdomain = $domain;
// directory - defaults to public_html/subdomain_name
$dir = 'public_html/user_site';
// create the subdomain
$sock = fsockopen($cpanel_host,2082);
if(!$sock) {
print('Socket error');
exit();
}
$pass = base64_encode("$cpanel_user:$cpanel_pass");
$in = "GET /frontend/$cpanel_skin/subdomain/doadddomain.html?rootdomain=$cpanel_host&domain=$subdomain&dir=$dir\r\n";
$in .= "HTTP/1.0\r\n";
$in .= "Host:$cpanel_host\r\n";
$in .= "Authorization: Basic $pass\r\n";
$in .= "\r\n";
fputs($sock, $in);
while (!feof($sock)) {
$result = fgets($sock, 128);
}
fclose($sock);
return $result;
}
createDomain('testing');
当我尝试直接在浏览器中使用链接看看会发生什么时,cpanel告诉我安全令牌有问题,我得到一个登录表单。
因此,我尝试拨打电话以生成安全令牌:
function createSession() { // Example details
$ip = "example.com";
$cp_user = "username";
$cp_pwd = "password";
$url = "https://example.com:2083/login";
$cookies = "/path/to/storage/for/cookies.txt";
// Create new curl handle
$ch=curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookies); // Save cookies to
curl_setopt($ch, CURLOPT_POSTFIELDS, "user=$cp_user&pass=$cp_pwd");
curl_setopt($ch, CURLOPT_TIMEOUT, 100020);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Execute the curl handle and fetch info then close streams.
$f = curl_exec($ch);
$h = curl_getinfo($ch);
curl_close($ch);
// If we had no issues then try to fetch the cpsess
if ($f == true and strpos($h['url'],"cpsess")){
// Get the cpsess part of the url
$pattern="/.*?(\/cpsess.*?)\/.*?/is";
$preg_res=preg_match($pattern,$h['url'],$cpsess);
}
// If we have a session then return it otherwise return empty string
$token = (isset($cpsess[1])) ? $cpsess[1] : "";
}
$test = createSession();
它成功创建了令牌。然后我尝试将安全令牌发送到另一个调用,所以它将是这样的:
$token . "/frontend/paper_lantern/subdomain/doadddomain.html?rootdomain=" . $main_domain . "&domain=" . $sub_domain_name . "&dir=public_html/subdomains/" . $sub_domain_name
但没有任何反应,没有错误,也没有创建子域。我怎样才能做到这一点?
经过大量的尝试和寻找,我终于明白了。我把它变成了一个类,所以对我和任何其他人来说都很容易使用。
class Subdomain {
const CP_user = env('CPANEL_USER', 'forge');
const CP_password = env('CPANEL_PASSWORD', 'forge');
const DOMAIN = env('CPANEL_DOMAIN', 'forge');
const URL = env('CPANEL_URL', 'forge');
public $token = "";
public function __construct() {
$token = self::createSession();
$this->token = $token;
}
private function createSession() {
$url = self::URL . "login";
$cookies = "/path/to/storage/for/cookies.txt";
// Create new curl handle
$ch=curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookies); // Save cookies to
curl_setopt($ch, CURLOPT_POSTFIELDS, "user=" . self::CP_user . "&pass=". self::CP_password);
curl_setopt($ch, CURLOPT_TIMEOUT, 100020);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Execute the curl handle and fetch info then close streams.
$f = curl_exec($ch);
$h = curl_getinfo($ch);
curl_close($ch);
// If we had no issues then try to fetch the cpsess
if ($f == true and strpos($h['url'],"cpsess")){
// Get the cpsess part of the url
$pattern="/.*?(\/cpsess.*?)\/.*?/is";
$preg_res=preg_match($pattern,$h['url'],$cpsess);
}
// If we have a session then return it otherwise return empty string
$token = (isset($cpsess[1])) ? $cpsess[1] : "";
return $token;
}
private function get_query( $action, $subdomain ){
$directory = $subdomain . "." . self::DOMAIN;
switch ($action) {
case 'create':
$query = self::URL . $this->token . "/json-api/cpanel?cpanel_jsonapi_func=addsubdomain&cpanel_jsonapi_module=SubDomain&cpanel_jsonapi_version=2&domain=$subdomain&rootdomain=" . self::DOMAIN . "&dir=$directory";
break;
case 'delete':
$query = self::URL . $this->token . "/json-api/cpanel?cpanel_jsonapi_func=delsubdomain&cpanel_jsonapi_module=SubDomain&cpanel_jsonapi_version=2&domain=".$subdomain.'.'.self::DOMAIN."&dir=$directory";
break;
case 'delete_dir':
$query = self::URL . $this->token . "/json-api/cpanel?cpanel_jsonapi_module=Fileman&cpanel_jsonapi_func=fileop&op=unlink&sourcefiles=$directory";
break;
}
return $query;
}
public function create($subdomain){
$query = self::get_query( 'create', $subdomain );
self::request($query);
}
public function delete($subdomain){
$query = self::get_query( 'delete', $subdomain );
$query_dir = self::get_query( 'delete_dir', $subdomain );
self::request($query, $query_dir);
}
public function request($query, $dir = false){
$curl = curl_init(); // Create Curl Object
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER,0); // Allow self-signed certs
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,0); // Allow certs that do not match the hostname
curl_setopt($curl, CURLOPT_HEADER,0); // Do not include header in output
curl_setopt($curl, CURLOPT_RETURNTRANSFER,1); // Return contents of transfer on curl_exec
$header[0] = "Authorization: Basic " . base64_encode(self::CP_user.":".self::CP_password) . "\n\r";
curl_setopt($curl, CURLOPT_HTTPHEADER, $header); // set the username and password
curl_setopt($curl, CURLOPT_URL, $query); // execute the query
$result = curl_exec($curl);
if ($result == false) {
error_log("curl_exec threw error \"" . curl_error($curl) . "\" for $query");
}
curl_close($curl);
if ($dir) {
self::request($dir);
}
print $result;
}
}
// how to use
$new_url = new Subdomain();
$new_url->create('mypage');
$new_url->delete('mypage');
注意: - 我将私有变量放在.env文件中。 - 删除将删除子域以及目录。 - 删除不会删除已创建的DNS,但尚未查看。