Recently, I've been trying to improve the sorry state of PHP's heap implementation, small step by small step since my free time significantly shrunk this year. Anyway, one of the low-hanging fruits is to makes parts of the _zend_mm_heap read-only, since it contains function pointers that are often overwritten in public exploits to transform a (limited) read/write primitive into an arbitrary code execution.
Changing memory's mode is done via mprotect, but it can only be done on a per-page page-aligned granularity. The easiest way that came to mind is to use C11's anonymous struct and union along with the aligned attribute to make the structure fit neatly on pages:
Unfortunately, this isn't really portable, as PAGE_SIZE can't be known at compilation-time. The recommended way to get its value is to call long sz = sysconf(_SC_PAGESIZE);.
The pull-request to implement this in php has a bit of fluff to integrate it with PHP's memory-management lifecycle, but should still be fairly readable. Unfortunately, it was rejected on the basis of lowering performances by 0.6% on my local benchmark.