php / php/php-src

Ability to pick PHP value by reference in FFI.

Open
#7,866 9 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Extension: ffi Feature Status: Needs Triage
Dominant language
C
Stars
40.4k
Forks
8.1k
Avg merge
2d 13h
Merged PRs (30d)
96

Description

Description

HI!
Currently the only way convert php value to FFI value is memcpy (or other ways with memory copying involved).
It could be wasting if we for example received large chunk from socket and need to deal with it through FFI.
For example,

/* Initial */
echo memory_get_usage(); // 348504

/* Got chunk of data */
$data = str_repeat('1', 512 << 10);
echo memory_get_usage(); // 876992

/* Defining the FFI type */
$type = FFI::arrayType(FFI::type('char'), [512 << 10]);
echo memory_get_usage(); // 877184

/* Allocating memory for type */
$ffiValue = FFI::new($type);
echo memory_get_usage(); // 1401984

/* And memcpy */
FFI::memcpy($ffiValue, $data, 512 << 10);
echo memory_get_usage(); 1402048

It would be great to have ability to reflect value from PHP to FFI using it by reference like so:

$data = str_repeat('1', 512 << 10);

/* @var FFI\CData $ffiValue */
$ffiValueCharArray = FFI::represent('char[]', &$data, size: 512 << 10); // No additional memory allocations for $data content

$ffiValueCharArray [1] = 5;
var_dump($data[1]); // $data changed by reference

$ffiValueInt32 = FFI::represent('int32_t', &$data, size: 4, offset: 12);
var_dump($ffiValueInt32->cdata); // substr($data, 12, 4) === "1111", we will get here 825307441

$ffiValueInt32->cdata = 10;
var_dump(bin2hex(substr($data, 12, 4))); // "0a000000"

Also could work not only with strings:

$int = 10;

$ffiValueInt64 = FFI::represent('int64_t', &$int); // length argument could be omitted if cast performed to fixed size type
var_dump($ffiValueInt64->cdata); // 10;

$ffiValueInt64->cdata = 20;
var_dump($int); // 20;

$readOverBoundary = FFI::represent('char[]', &$int, 10); // Exception: attempt to read over boundary

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the FFI::type, FFI::arrayType, FFI::new, and FFI::memcpy entry points shown in the examples, then determine whether the proposed reference semantics fit PHP's value and memory model. Done means reaching a maintainer-approved design for the proposed FFI::represent behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, php
Domain
backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.