调用函数(Calling Functions)

Phalcon API 在 Zend API 的基础上实现了 phalcon_call_method_with_params 函数,并以此为基础定义了宏 PHALCON_CALL_FUNCTION,利用这些 API 可以很轻松的调用内核及自定义函数。

.. code-block:: c

  1. // $length = strlen(some_variable);
  2. PHALCON_CALL_FUNCTION(&length, "strlen", &some_variable);
  3. // Calling substr() with its 3 arguments returning the substring into "part"
  4. PHALCON_CALL_FUNCTION(&part, "substr", &some_variable, &start, &length);
  5. // Calling ob_start(), this function does not return anything
  6. PHALCON_CALL_FUNCTION(NULL, "ob_start");
  7. // Closing a file with fclose
  8. PHALCON_CALL_FUNCTION(NULL, "fclose", file_handler);

如上所述,PHP 已经有帮我们做了很多事情,C 的扩展并不意味着我们要重新发明轮子。我们也要尽量避免使用 C 非常底层的特性。使用 PHP 函数帮助我们实现和 PHP 编程中类似的行为,这样我们就可以避免可能出现的错误。

下面是 Zend API 的相关定义:

.. code-block:: c

  1. #define call_user_function_ex(function_table, object, function_name, retval_ptr, param_count, params, no_separation, symbol_table) \
  2. _call_user_function_ex(object, function_name, retval_ptr, param_count, params, no_separation)

除了 call_user_function_ex 以及 call_user_function,还有zend_call_method;

文件读写

The following code opens a file in C and write something on it. Its functionality is limited because it only works on local files:

  1. FILE * pFile;
  2. pFile = fopen ("myfile.txt","w");
  3. if (pFile != NULL) {
  4. fputs ("fopen example",pFile);
  5. fclose (pFile);
  6. }

Now write the same code using the PHP userland:

  1. ZVAL_STRING(&mode, "w");
  2. PHALCON_CALL_FUNCTION(&file_handler, "fopen", &file_path, &mode);
  3. if (PHALCON_IS_NOT_FALSE(&file_handler)) {
  4. ZVAL_STRING(&text, "fopen example");
  5. PHALCON_CALL_FUNCTION(NULL, "fputs", &file_handler, &text);
  6. PHALCON_CALL_FUNCTION(NULL, "fclose", &file_handler);
  7. }

Although both codes perform the same task, the former is more powerful as it could open a PHP stream, a file in a URL or a local file. We can also write the same code using the PHP API, without losing functionality. However, the above code is more familiar if we are primarily PHP developers.

The same code in PHP:

  1. <?php
  2. $fp = fopen($file_path, "w");
  3. if($fp){
  4. fputs($fp, "fopen example");
  5. fclose($fp);
  6. }