Since the $options are not documented, I'm going to clarify what they mean here in the comments. Behind the scenes, in the source code for /ext/openssl/openssl.c:
EVP_EncryptInit_ex(&cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
if (options & OPENSSL_ZERO_PADDING) {
EVP_CIPHER_CTX_set_padding(&cipher_ctx, 0);
}
And later:
if (options & OPENSSL_RAW_DATA) {
outbuf[outlen] = '\0';
RETVAL_STRINGL((char *)outbuf, outlen, 0);
} else {
int base64_str_len;
char *base64_str;
base64_str = (char*)php_base64_encode(outbuf, outlen, &base64_str_len);
efree(outbuf);
RETVAL_STRINGL(base64_str, base64_str_len, 0);
}
So as we can see here, OPENSSL_ZERO_PADDING has a direct impact on the OpenSSL context. EVP_CIPHER_CTX_set_padding() enables or disables padding (enabled by default). So, OPENSSL_ZERO_PADDING disables padding for the context, which means that you will have to manually apply your own padding out to the block size. Without using OPENSSL_ZERO_PADDING, you will automatically get PKCS#7 padding.
OPENSSL_RAW_DATA does not affect the OpenSSL context but has an impact on the format of the data returned to the caller. When OPENSSL_RAW_DATA is specified, the returned data is returned as-is. When it is not specified, Base64 encoded data is returned to the caller.
Hope this saves someone a trip to the PHP source code to figure out what the $options do. Pro developer tip: Download and have a copy of the PHP source code locally so that, when the PHP documentation fails to live up to quality expectations, you can see what is actually happening behind the scenes.