C -PHP扩展名:为什么INT VAR更改为0



我正在对C上开发一些PHP扩展。我在C代码顶部的功能很少,几个变量(char and int(在全球定义。在PHP侧,我调用第一个功能,并传递SSH_PORT参数的一些值-22。此值设置为全局var。然后我调用第二个功能。但是,当我调用第三函数时-SSH_PORT变量突然获得0值?为什么 ?代码如下:

#include <php.h>
#include "super_ssh.h"
#include <libssh2.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <pthread.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifndef INADDR_NONE
#define INADDR_NONE (in_addr_t)-1
#endif
    char *ssh_ip, *ssh_username, *ssh_password, *remote_host, *last_error = "";
    size_t ssh_ip_len, ssh_username_len, ssh_password_len, remote_host_len;
    int ssh_port = 0, remote_port = 0, local_port = 0, to_close_tunnel = 0, thread_is_runnning = 0, is_authenticated = 0;
    PHP_FUNCTION(super_ssh_connect) {
      if (zend_parse_parameters(
        ZEND_NUM_ARGS(),
        "sl",
        &ssh_ip,
        &ssh_ip_len,
        &ssh_port
      ) == FAILURE) {
          return;
      }
      RETURN_LONG(ssh_port);
    }
    PHP_FUNCTION(super_ssh_authenticate) {
      if (zend_parse_parameters(
        ZEND_NUM_ARGS(),
        "ss",
        &ssh_username,
        &ssh_username_len,
        &ssh_password,
        &ssh_password_len
      ) == FAILURE) {
          return;
      }
      RETURN_LONG(ssh_port);
    }
    PHP_FUNCTION(super_ssh_open_tunnel) {
      if (zend_parse_parameters(
        ZEND_NUM_ARGS(),
        "sll",
        &remote_host,
        &remote_host_len,
        &remote_port,
        &local_port
      ) == FAILURE) {
          return;
      }
      RETURN_LONG(ssh_port);
    }


    ZEND_BEGIN_ARG_INFO_EX(arginfo_super_ssh_connect, 0, 0, 2)
      ZEND_ARG_INFO(0, ssh_ip)
      ZEND_ARG_INFO(0, ssh_port)
    ZEND_END_ARG_INFO()
    ZEND_BEGIN_ARG_INFO_EX(arginfo_super_ssh_authenticate, 0, 0, 2)
        ZEND_ARG_INFO(0, ssh_username)
      ZEND_ARG_INFO(0, ssh_password)
    ZEND_END_ARG_INFO()
    ZEND_BEGIN_ARG_INFO_EX(arginfo_super_ssh_open_tunnel, 0, 0, 3)
      ZEND_ARG_INFO(0, remote_host)
      ZEND_ARG_INFO(0, remote_port)
      ZEND_ARG_INFO(0, local_port)
    ZEND_END_ARG_INFO()
    zend_function_entry super_ssh_functions[] = {
      PHP_FE(super_ssh_connect, arginfo_super_ssh_connect)
      PHP_FE(super_ssh_authenticate, arginfo_super_ssh_authenticate)
      PHP_FE(super_ssh_open_tunnel, arginfo_super_ssh_open_tunnel)
      PHP_FE_END
    };
    zend_module_entry super_ssh_module_entry = {
      STANDARD_MODULE_HEADER,
      PHP_SUPER_SSH_EXTNAME,
      super_ssh_functions,
      NULL,
      PHP_MSHUTDOWN(super_ssh),
      NULL,
      NULL,
      NULL,
      PHP_SUPER_SSH_VERSION,
      STANDARD_MODULE_PROPERTIES,
    };
    ZEND_GET_MODULE(super_ssh);

和PHP侧的代码:

<?php
var_dump(super_ssh_connect("234.43.23.3", 22));
var_dump(super_ssh_authenticate("dfds", "mofsdfdsnitor"));
var_dump(super_ssh_open_tunnel("server", 993, 4444));

实际结果是:

int(22(int(22(int(0(

预期结果是:

int(22(int(22(int(22(

所以问题是为什么SSH_PORT变量获得0值?我不在任何地方设置!真的无法理解:(

有趣的是,问题是Apache PHP的实际问题。因此,当我从浏览器中运行脚本时,就会发生这种情况。(apache2 php(

如果我尝试对PHP CLI进行相同的汇编,则可以按预期工作,输出为:

int(22(int(22(int(22(

可能是在某种程度上与垃圾收集器接触吗?或者,也许您可以为我的代码提供更好的方法如何与变量一起使用?

我的环境:

Ubuntu 18.04.1 LTS,Apache2 PHP版本7.2.17-1和PHP CLI是PHP 7.2.2(CLI((构建:APR 29 2019 09:57:40((ZTS调试(

我注意到有问题的代码,如果我评论以下代码frpm第三super_ssh_open_tunnel函数 - 它可以工作。

评论此代码使其正常工作,没有此代码,我在SSH_PORT VAR

中仍然有22个
 if (zend_parse_parameters(
        ZEND_NUM_ARGS(),
        "sll",
        &remote_host,
        &remote_host_len,
        &remote_port,
        &local_port
      ) == FAILURE) {
          return;
      }

实际上,我认为您的行为是不确定的。

首先将PHP_FUNCTION扩展到void zif_FUNCNAME(zend_execute_data *execute_data, zval *return_value)

根据C标准:

6.8.6.4返回语句

约束

  1. 带有表达式的返回语句不得出现在返回类型无效的函数中。没有表达式的返回语句只能出现在返回类型无效的函数中。

6.9.1功能定义

  1. 如果终止函数的},并且函数调用的值由呼叫者使用,则行为是未定义的。

因此,在您的情况下,zend_parse_parameters返回FAILURE,然后将其转换为"结束前结束,然后才能关闭{,所以这就是为什么ssh_port的值永远不会返回。

zend_parse_parameters失败的原因是,其中一个参数与0

没有初始化。

相关内容

  • 没有找到相关文章

最新更新