{"action":"created","issue":{"url":"https://api.github.com/repos/swoole/swoole-src/issues/683","repository_url":"https://api.github.com/repos/swoole/swoole-src","labels_url":"https://api.github.com/repos/swoole/swoole-src/issues/683/labels{/name}","comments_url":"https://api.github.com/repos/swoole/swoole-src/issues/683/comments","events_url":"https://api.github.com/repos/swoole/swoole-src/issues/683/events","html_url":"https://github.com/swoole/swoole-src/issues/683","id":155245510,"number":683,"title":"server::set方法具有副作用，可能产生难以调试的bug","user":{"login":"chefxu","id":1010775,"avatar_url":"https://avatars.githubusercontent.com/u/1010775?v=3","gravatar_id":"","url":"https://api.github.com/users/chefxu","html_url":"https://github.com/chefxu","followers_url":"https://api.github.com/users/chefxu/followers","following_url":"https://api.github.com/users/chefxu/following{/other_user}","gists_url":"https://api.github.com/users/chefxu/gists{/gist_id}","starred_url":"https://api.github.com/users/chefxu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chefxu/subscriptions","organizations_url":"https://api.github.com/users/chefxu/orgs","repos_url":"https://api.github.com/users/chefxu/repos","events_url":"https://api.github.com/users/chefxu/events{/privacy}","received_events_url":"https://api.github.com/users/chefxu/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-05-17T12:19:46Z","updated_at":"2016-05-18T03:16:19Z","closed_at":null,"body":"正常的代码：\r\n\r\n```php\r\n<?php\r\nerror_reporting(E_ERROR | E_WARNING);\r\n$serv = new swoole_server('0.0.0.0', '9501', SWOOLE_PROCESS, SWOOLE_SOCK_TCP);\r\n$config = [];\r\n$options = array(\r\n        'worker_num' => $config['worker_num'],\r\n        'log_file' => $config['package_eof'],\r\n        );\r\n\r\n// $serv->set($options);\r\n\r\nvar_dump(gettype($options['log_file']));\r\nvar_dump(gettype($a[0]));\r\n$b[0] = '1';\r\nvar_dump(gettype($b));\r\n$c[] = '123';\r\nvar_dump(gettype($c));\r\n```\r\n\r\n输出:\r\n\r\n```\r\nstring(4) \"NULL\"\r\nstring(4) \"NULL\"\r\nstring(5) \"array\"\r\nstring(5) \"array\"\r\n```\r\n\r\n有副作用的代码：\r\n\r\n```php\r\n<?php\r\nerror_reporting(E_ERROR | E_WARNING);\r\n$serv = new swoole_server('0.0.0.0', '9501', SWOOLE_PROCESS, SWOOLE_SOCK_TCP);\r\n$config = [];\r\n$options = array(\r\n        'worker_num' => $config['worker_num'],\r\n        'log_file' => $config['package_eof'],\r\n        );\r\n\r\n$serv->set($options);\r\n\r\nvar_dump(gettype($options['log_file']));\r\nvar_dump(gettype($a[0]));\r\n$b[0] = '1';  // 这里变成了字符串操作\r\nvar_dump(gettype($b));  \r\n$c[] = '123'; // 这里干脆直接异常\r\nvar_dump(gettype($c));\r\n```\r\n\r\n输出：\r\n\r\n```\r\nstring(4) \"NULL\"\r\nstring(6) \"string\"\r\nstring(6) \"string\"\r\nPHP Fatal error:  [] operator not supported for strings in /tmp/test.php on line 16\r\n```\r\n\r\n查看了一下代码：\r\n类似下面的代码， 直接对参数进行了类型转换。\r\n```c\r\n    if (sw_zend_hash_find(vht, ZEND_STRS(\"enable_unsafe_event\"), (void **) &v) == SUCCESS)\r\n    {\r\n        convert_to_boolean(v);\r\n        serv->enable_unsafe_event = Z_BVAL_P(v);\r\n    }\r\n```\r\n\r\n在我的case中， 一个是调用set后，options的元素的类型发生了变化， 与期望不一致； 另一个是如果options里指向了不存在的数组元素，对一个不存在的数组元素做强制转换会影响后续所有数组的行为， 这个可能发生在和swoole毫不相干的地方，增加调试的困难程度。\r\n\r\n我试过两个方案， 一个是做参数检查， 一个是做一下zval复制， 都可以解决这个问题， 但是感觉实现上都不是很优雅。\r\n\r\nPS： pdo的setAttribute方法也有副作用， 不过做了参数检查， 避免了我提到的第二个问题。"},"comment":{"url":"https://api.github.com/repos/swoole/swoole-src/issues/comments/219914737","html_url":"https://github.com/swoole/swoole-src/issues/683#issuecomment-219914737","issue_url":"https://api.github.com/repos/swoole/swoole-src/issues/683","id":219914737,"user":{"login":"matyhtf","id":2017766,"avatar_url":"https://avatars.githubusercontent.com/u/2017766?v=3","gravatar_id":"","url":"https://api.github.com/users/matyhtf","html_url":"https://github.com/matyhtf","followers_url":"https://api.github.com/users/matyhtf/followers","following_url":"https://api.github.com/users/matyhtf/following{/other_user}","gists_url":"https://api.github.com/users/matyhtf/gists{/gist_id}","starred_url":"https://api.github.com/users/matyhtf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matyhtf/subscriptions","organizations_url":"https://api.github.com/users/matyhtf/orgs","repos_url":"https://api.github.com/users/matyhtf/repos","events_url":"https://api.github.com/users/matyhtf/events{/privacy}","received_events_url":"https://api.github.com/users/matyhtf/received_events","type":"User","site_admin":false},"created_at":"2016-05-18T03:16:19Z","updated_at":"2016-05-18T03:16:19Z","body":"感谢反馈，我们增加一个 IS_NULL 判断逻辑。"}}