适用于 Linux 的 PHP 扩展:需要进行现实检查!
好的,我已经编写了第一个 PHP 函数扩展。它有效,但只是一个概念验证。现在我正在写另一篇文章,它实际上符合老板的要求。
我想从所有 PHP 专家那里知道这段代码是否有意义。我是否已经很好地掌握了诸如 emalloc 之类的东西,或者是否有一些东西稍后会扭转并试图咬掉我的手?
以下是其中一项功能的代码。它返回一个经过 Blowfish 加密的字符串的 base64。调用该函数时,会为其提供两个字符串:要加密和编码的文本以及加密阶段的密钥。它没有使用 PHP 自己的 base64 函数,因为此时我不知道如何链接到它们。出于同样的原因,它没有使用 PHP 自己的 mcrypt 函数。相反,它链接在 SSLeay BF_ecb_encrypt
函数中。
PHP_FUNCTION(Blowfish_Base64_encode)
{
char *psData = NULL;
char *psKey = NULL;
int argc = ZEND_NUM_ARGS();
int psData_len;
int psKey_len;
char *Buffer = NULL;
char *pBuffer = NULL;
char *Encoded = NULL;
BF_KEY Context;
int i = 0;
unsigned char Block[ 8 ];
unsigned char * pBlock = Block;
char *plaintext;
int plaintext_len;
int cipher_len = 0;
if (zend_parse_parameters(argc TSRMLS_CC, "ss", &psData, &psData_len, &psKey, &psKey_len) == FAILURE)
return;
Buffer = (char *) emalloc( psData_len * 2 );
pBuffer = Buffer;
Encoded = (char *) emalloc( psData_len * 4 );
BF_set_key( &Context, psKey_len, psKey );
plaintext = psData;
plaintext_len = psData_len;
for (;;)
{
if (plaintext_len--)
{
Block[ i++ ] = *plaintext++;
if (i == 8 )
{
BF_ecb_encrypt( Block, pBuffer, &Context, BF_ENCRYPT );
pBuffer += 8;
cipher_len += 8;
memset( Block, 0, 8 );
i = 0;
}
} else {
BF_ecb_encrypt( Block, pBuffer, &Context, BF_ENCRYPT );
cipher_len += 8;
break;
}
}
b64_encode( Encoded, Buffer, cipher_len );
RETURN_STRINGL( Encoded, strlen( Encoded ), 0 );
}
您会注意到我有两个 emalloc
调用,分别针对 Encoded
和 Buffer
。只有 Encoded
被传递回调用者,所以我担心 Buffer 不会被释放。是这样吗?我应该使用 malloc/free 作为缓冲区吗?
如果还有任何其他明显的错误,我真的很高兴知道。
Okay, I've written my first functional PHP extension. It worked but it was a proof-of-concept only. Now I'm writing another one which actually does what the boss wants.
What I'd like to know, from all you PHP-heads out there, is whether this code makes sense. Have I got a good grasp of things like emalloc
and the like, or is there stuff there that's going to turn around later and try to bite my hand off?
Below is the code for one of the functions. It returns a base64 of a string that has also been Blowfish encrypted. When the function is called, it is supplied with two strings, the text to encrypt and encode, and the key for the encryption phase. It's not using PHP's own base64 functions because, at this point, I don't know how to link to them. And it's not using PHP's own mcrypt functions for the same reason. Instead, it links in the SSLeay BF_ecb_encrypt
functions.
PHP_FUNCTION(Blowfish_Base64_encode)
{
char *psData = NULL;
char *psKey = NULL;
int argc = ZEND_NUM_ARGS();
int psData_len;
int psKey_len;
char *Buffer = NULL;
char *pBuffer = NULL;
char *Encoded = NULL;
BF_KEY Context;
int i = 0;
unsigned char Block[ 8 ];
unsigned char * pBlock = Block;
char *plaintext;
int plaintext_len;
int cipher_len = 0;
if (zend_parse_parameters(argc TSRMLS_CC, "ss", &psData, &psData_len, &psKey, &psKey_len) == FAILURE)
return;
Buffer = (char *) emalloc( psData_len * 2 );
pBuffer = Buffer;
Encoded = (char *) emalloc( psData_len * 4 );
BF_set_key( &Context, psKey_len, psKey );
plaintext = psData;
plaintext_len = psData_len;
for (;;)
{
if (plaintext_len--)
{
Block[ i++ ] = *plaintext++;
if (i == 8 )
{
BF_ecb_encrypt( Block, pBuffer, &Context, BF_ENCRYPT );
pBuffer += 8;
cipher_len += 8;
memset( Block, 0, 8 );
i = 0;
}
} else {
BF_ecb_encrypt( Block, pBuffer, &Context, BF_ENCRYPT );
cipher_len += 8;
break;
}
}
b64_encode( Encoded, Buffer, cipher_len );
RETURN_STRINGL( Encoded, strlen( Encoded ), 0 );
}
You'll notice that I have two emalloc
calls, for Encoded
and for Buffer
. Only Encoded
is passed back to the caller, so I'm concerned that Buffer won't be freed. Is that the case? Should I use malloc/free for Buffer
?
If there are any other glaring errors, I'd really appreciate knowing.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
emalloc() 为每个请求分配内存,并在运行时结束时自动 free() 。
但是,您应该使用以下命令编译 PHP
它会告诉您是否出现任何问题(如果您使用了 e*() 函数并且在您的文件中设置了
report_memleaks
,它可以检测内存泄漏php.ini)。是的,你应该使用 efree() 缓冲区。
emalloc() allocates memory per request, and it's free()'d automatically when the runtime ends.
You should, however, compile PHP with
It will tell you if anything goes wrong (it can detect memory leaks if you've used the e*() functions and
report_memleaks
is set in your php.ini).And yes, you should efree() Buffer.
是的,您应该在返回之前使用
efree
释放它。尽管 PHP 有安全网,并且使用
emalloc
分配的内存将在请求结束时释放,但泄漏内存仍然是一个错误,并且如果使用report_memleaks 运行调试构建,则会发出警告= 开
。Yes, you should free it with
efree
before returning.Although PHP has safety net and memory allocated with
emalloc
will be freed at the end of the request, it's still a bug to leak memory and, depending you will warned if running a debug build withreport_memleaks = On
.