1,创建一个新的扩展
./ext_skel --extname=output1
2,修改config.m4,去掉没用的注释语句
cd output1
vi config.m4
3,编写代码
vi output1.c
#修改confirm_output_compiled
PHP_FUNCTION(confirm_output_compiled)
{
char *arg = NULL;
int arg_len, len;
char *strg;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
return;
}
FILE *fp = NULL;
long fsize;
char *buffer;
size_t result;
fp = fopen(arg, "r");
if (fp == NULL) {
RETURN_FALSE;
}
fseek(fp, 0, SEEK_END);
fsize = ftell(fp);
rewind(fp);
buffer = (char *)malloc(sizeof(char) * fsize);
result = fread(buffer, 1, fsize, fp);
fclose(fp);
//输出Content-type
char *content_type = "'Content-type: image/jpeg";
sapi_header_line ctr = {0};
ctr.line = content_type;
ctr.line_len = strlen(content_type);
ctr.response_code = 200;
sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
//输出图像
php_output_write(buffer, result TSRMLS_CC);
php_output_end_all(TSRMLS_C);
free(buffer);
RETURN_TRUE;
}
4,结构
//1, 输出header操作
// SAPI.h
typedef struct {
char *line; //输出的内容,记得需要自已释放内存
uint line_len; //输出内容的长度
long response_code; //状态码
} sapi_header_line;
typedef enum { /* Parameter: */
SAPI_HEADER_REPLACE, /* sapi_header_line* */
SAPI_HEADER_ADD, /* sapi_header_line* */
SAPI_HEADER_DELETE, /* sapi_header_line* */
SAPI_HEADER_DELETE_ALL, /* void */
SAPI_HEADER_SET_STATUS /* int */
} sapi_header_op_enum;
#调用sapi_header_op输出内容
char *content_type = "'Content-type: image/jpeg";
sapi_header_line ctr = {0};
ctr.line = content_type;
ctr.line_len = strlen(content_type);
ctr.response_code = 200;
sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
//2, 输出内容操作
//main/php_output.h
ZEND_BEGIN_MODULE_GLOBALS(output)
int flags;
zend_stack handlers;
php_output_handler *active;
php_output_handler *running;
const char *output_start_filename;
int output_start_lineno;
ZEND_END_MODULE_GLOBALS(output)
#define PHP_OUTPUT_IMPLICITFLUSH 0x01
#define PHP_OUTPUT_DISABLED 0x02 //当flags=PHP_OUTPUT_DISABLED时,则会禁止输出
#define PHP_OUTPUT_WRITTEN 0x04
#define PHP_OUTPUT_SENT 0x08
#define PHP_OUTPUT_ACTIVE 0x10
#define PHP_OUTPUT_LOCKED 0x20
#define PHP_OUTPUT_ACTIVATED 0x100000
//当flags=PHP_OUTPUT_ACTIVATED,会调用sapi_module.ub_write输出, 每个SAPI都有自已的实现, cli中是调用sapi_cli_single_write()
php_output_write(); //输出,有buffer, 调用php_output_op()
php_output_write_unbuffered();//输出,没有buffer,调用PHP_OUTPUT_ACTIVATED,会调用sapi_module.ub_write
php_output_set_status(); //用于SAPI设置output.flags ,
php_output_get_status(); //获取output.flags的值
php_output_op();//
5,宏
#define PHPWRITE(str, str_len) php_output_write((str), (str_len) TSRMLS_CC)
#define PHPWRITE_H(str, str_len) php_output_write_unbuffered((str), (str_len) TSRMLS_CC)
#define PUTC(c) (php_output_write(&(c), 1 TSRMLS_CC), (c))
#define PUTC_H(c) (php_output_write_unbuffered(&(c), 1 TSRMLS_CC), (c))
#define PUTS(str) do { \
const char *__str = (str); \
php_output_write(__str, strlen(__str) TSRMLS_CC); \
} while (0)
#define PUTS_H(str) do { \
const char *__str = (str); \
php_output_write_unbuffered(__str, strlen(__str) TSRMLS_CC); \
} while (0)