运行 PHP 带有基础进程的脚本 - Mac OS 蒙特雷 - Swift

Running PHP script with Foundation Process - Mac OS Monterey - Swift

每个人都知道一些计算机一旦设置好,到它的生命结束时就无法触摸了。我有这种设备。这是一个简单的 macOS 应用程序,可以从 MySQL 获取数据并将其发送到外部服务器。由于某些原因,否则无法完成。

目标是 运行 PHP macOS Monterey 进程任务中的脚本。为了实现它,我在清晰的实例上做了几个步骤:

  1. Brew 安装 - Brew
  2. PHP 安装 - brew install php
  3. 正在准备 PHP 脚本:
<?php
    $servername = "www.example.com";
    $username = "login";
    $password = "pass";
    $dbname = "database";
    $port = 12345;

    $db = new mysqli($servername, $username, $password, $dbname, $port);
    
    if ($db->connect_error) {
        die('Connect Error (' . $db->connect_errno . ') ' . $db->connect_error);
    }
    
    $query = $argv[1];
    $result = mysqli_query($db, $query);
    $db->next_result();
    
    $rows = [];
    while($row = $result->fetch_array(MYSQLI_ASSOC)) {
        $object = new stdClass();
        foreach ($row as $key => $value) {
            $object->$key = $value;
        }
        
        $rows[] = $object;
    }
    
    echo json_encode($rows);
    exit;
?>
  1. 准备 Swift 代码到 运行 PHP 脚本:
     let outputPipe = Pipe()
     let errorPipe = Pipe()

     let phpPath = Bundle.main.path(forResource: "Query", ofType: "php")!
     
     let process = Process()
     process.launchPath = "/opt/homebrew/Cellar/php/8.1.1/bin/php" //Could be found by using `brew info PHP` in terminal
     process.arguments = [phpPath, "call prepared_database_function(null)"]

     process.standardOutput = outputPipe
     process.standardError = errorPipe

     process.terminationHandler = { _ in
         let data = outputPipe.fileHandleForReading.readDataToEndOfFile()
         print(String(data: data, encoding: .utf8))

         let errorData = errorPipe.fileHandleForReading.readDataToEndOfFile()
         print(String(data: errorData, encoding: .utf8))
     }

     do {
         try process.run()
     } catch {
         print(error)
     }
  1. 我正在运行宁计划和...

什么也没发生...问题是 Activity Monitor 呈现 PHP 任务,我可以 Force Quit这个过程。我什么时候会调用 terminationHandler 然后打印输出。

如何强制进程自行结束,就像在终端中完成的那样?

我找到了函数调用顺序的解决方案。 macOS 应用程序中有 运行 PHP 脚本的正确 Swift 代码:

let errorPipe = Pipe()
let outputPipe = Pipe()
let phpPath = Bundle.main.path(forResource: "Query", ofType: "php")!

let process = Foundation.Process()
process.executableURL = URL(fileURLWithPath: "/opt/homebrew/Cellar/php/8.1.1/bin/php") //Could be found by using `brew info php` in terminal
process.arguments = [phpPath, "call prepared_database_function(null)"]

process.standardOutput = outputPipe
process.standardError = errorPipe
        
do {
     try process.run()
} catch {
     print(error)
}
        
let data = outputPipe.fileHandleForReading.readDataToEndOfFile()
let errorData = errorPipe.fileHandleForReading.readDataToEndOfFile()
        
process.terminationHandler = { process in
    print(String(data: data, encoding: .utf8))
    print(String(data: errorData, encoding: .utf8))
}