我有一台有一个小站点的macOS服务器,该站点使用say命令将文本片段转换为音频。升级到Sierra后,除了一件事情外,一切都变得顺利了:将php包裹在say中后,exec()命令不再起作用。该页面只是超时。也没有发现错误。<?php try { exec('/usr/bin/say "hello"'); } catch (Exception $e) { echo $e->getMessage(); }?>通常,我会使用say -o filename保存音频片段,但我尝试了所有变体以及其他运行良好的shell命令,包括在我的输出文件夹中创建文件。有趣的是,如果我从命令行运行它,则可以正常工作-大声说出来或创建一个输出文件。macOS Sierra具有PHP 5.6.24,所以我认为safe_mode不适用,对吗?我想强调一下,对于新操作系统,PHP或say命令的更改是最近的。是的,我确实调查过并尝试了不同的输出和stderr重定向,但是脚本只是挂起了。在事件查看器(相当于say的GUI)中看到top命令,我尝试对其进行采样,不确定是否有帮助:2695 Thread_1742595 DispatchQueue_1: com.apple.main-thread (serial)+ 2695 start (in libdyld.dylib) + 1 [0x7fffb0f58255]+ 2695 ??? (in say) load address 0x10907d000 + 0x1fac [0x10907efac]+ 2695 NewSpeechChannel (in SpeechSynthesis) + 52 [0x7fff9acd3f19]+ 2695 SpeechChannelHandle::SpeechChannelHandle() (in SpeechSynthesis) + 265 [0x7fff9acd797f]+ 2695 dispatch_once_f (in libdispatch.dylib) + 38 [0x7fffb0f220e5]+ 2695 _dispatch_client_callout (in libdispatch.dylib) + 8 [0x7fffb0f22128]+ 2695 ___ZN13SpeechGlobals8InstanceEv_block_invoke (in SpeechSynthesis) + 28 [0x7fff9acd54da]+ 2695 SpeechGlobals::SpeechGlobals() (in SpeechSynthesis) + 471 [0x7fff9acd56db]+ 2695 xpc_connection_send_message_with_reply_sync (in libxpc.dylib) + 154 [0x7fffb11b65a8]+ 2695 dispatch_mach_send_with_result_and_wait_for_reply (in libdispatch.dylib) + 45 [0x7fffb0f3cf39]+ 2695 _dispatch_mach_send_and_wait_for_reply (in libdispatch.dylib) + 591 [0x7fffb0f3cad4]+ 2695 mach_msg (in libsystem_kernel.dylib) + 55 [0x7fffb107e867]+ 2695 mach_msg_trap (in libsystem_kernel.dylib) + 10 [0x7fffb107f41a]2695 Thread_1742600 2695 start_wqthread (in libsystem_pthread.dylib) + 13 [0x7fffb116f211] 2695 _pthread_wqthread (in libsystem_pthread.dylib) + 1426 [0x7fffb116f7b5] 2695 __workq_kernreturn (in libsystem_kernel.dylib) + 10 [0x7fffb10874e6]这些是统计信息: 从打开的文件和端口中,我可以看到我同时将stdout和stderr都设置为/private/var/log/apache2/error_log,但那里什么也没有显示。另外,尝试以更复杂的运行来捕获输出,但是没有乐趣,只是超时(脚本文件夹也是可写的):<?php try { $pipes = array(); proc_close(proc_open("say hi", array(0 => array("pipe", "r"), 1 => array("pipe", "r"), 2 => array("pipe", "r")), $pipes, dirname(__FILE__), null)); } catch (Exception $e) { error_log($e->getMessage()); }?>更新:高塞拉山脉是相同的。最终更新:安装Mojave(删除了大部分Server.app功能)之后,我添加了MAMP来处理此任务。如果您愿意,请自己尝试-位于macspeaks.com。故事继续:在安装Catalina的过程中,还是MAMP更新了? (现在是5.5版),我再次杀死了它。叹... 最佳答案 我也遇到过同样的问题。这是我刚想出的解决方法,但老实说,我认为能够播放基于apache的php脚本中的音频是一个很大的挑战。我对为什么会发生这种情况有一些想法,但是经过多次测试,我似乎破坏了我自己的理论。我认为这可能与没有活跃的TTY有关。我无法通过启动带有sudo -i的shell和php中的很多其他属性来播放音频,但是我却能够使用本地终端上的所有相同命令来播放音频,事实证明,也可以通过SSH'ing进入计算机,这导致了我最新的解决方法。再一次,我认为这是过大的方法,但是到目前为止,这是我能够在基于Web的php驱动的脚本(主要是与地理围栏相关的脚本)中恢复音频的唯一方法。所以,我们开始吧,是的,我了解其中涉及的风险和愚蠢性:在我的php脚本中,使用类似以下命令在/tmp目录中生成一个音频文件:exec "sudo -u <username> /usr/bin/say -o /tmp/outputfile.aiff --voice=Ava \"<What to Say>\"";然后,在生成音频文件之后,我发现从apache/php播放(并且实际上听到了输出)的唯一方法是使用Expect脚本在本地ssh并播放。所以我的下一行是:exec "sudo -u <username> -i ~<username>/expectscript";我的期望脚本如下:#!/usr/bin/expect -fspawn /usr/bin/ssh localhostexpect "Password"send "<PASSWORD>\r"expect "<username>"send "/usr/bin/afplay /tmp/outputfile.aiff\r"expect "<username>"send "/usr/bin/touch /tmp/touchthis\r"expect "<username>"send "exit\r"确保使用用户名(显然没有)替换上面的所有<username>,并用密码替换<PASSWORD>。如果您的bash提示中不包含您的用户名,则可能需要调整Expect脚本,因为这是我在我的Expect脚本中用来查找返回的提示的方式。这样做只是为了确定期望脚本是否起作用,您可以引用上次触摸文件的时间。我希望这会引起真正原因的讨论,并且我们可以确定一个更合理的解决方案。我遇到了很多麻烦,试图找到使它起作用的不同方法,我创建了Automator应用程序,并从PHP调用了这些应用程序(没有用。)我以用户身份在shell中启动了shell,所有命令的执行始终成功完成,只是没有音频输出。我尝试过的所有解决方案都可以在终端上正常运行(甚至可以从终端上运行php),而不能从Apache/PHP上运行。关于php - macOS Sierra中的更改阻止 "say"在PHP脚本中执行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40233677/ 10-11 03:29