# Exposing object handles to userland

- Thread: https://externals.io/message/99751
- Original archive: https://news-web.php.net/php.internals/99751
- Started by tyson andre on 2017-07-05T00:01:26+00:00
- Messages: 14
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #99751 — tyson andre — 2017-07-05T00:01:26+00:00

URL: https://externals.io/message/99751#99751

There was a proposal back in 2015 to implement
a function spl_object_id(object $o) : int`,
which directly returns the object handle
(similar to `spl_object_hash`, but as an integer, not a string).
I'm interested in finishing implementing spl_object_id for php 7.2 

I already have working code implementing `spl_object_id()` at
https://github.com/TysonAndre/php-src/pull/1
The implementation XORs the object handle with the 
exact same random bits that `spl_object_hash` would.

Previous emails from 2015 can be seen here:
- https://marc.info/?t=143835274500003&r=1&w=2

Previous comment by a PHP maintainer in support of `spl_object_id()`
- https://marc.info/?l=php-internals&m=143837339210596&w=2

I'm unsure if an RFC is necessary. I have two pending questions.

- Can two objects can have the same object id
  but different object handlers?
  (e.g. iterators of some built in classes?)
  I'm not familiar enough with PHP's history to be sure.
- Can the the largest object handle be larger
  than the size of `zend_long` in 32-bit systems?

Example places where this would be useful:

1. https://marc.info/?l=php-internals&m=143849841618494&w=2

2. I also recently wanted to track a large number of (cloneable)
   small sets of objects in an application that sometimes used a lot of memory,
   and the fact that arrays support copy on write helped save memory
   relative to SplObjectHash if arrays and integer keys were used.
   See https://github.com/etsy/phan/pull/729#issuecomment-299289378

- Tyson Andre (tandre)

---

## #99752 — Stanislav Malyshev — 2017-07-05T03:27:51+00:00

URL: https://externals.io/message/99751#99752 · In reply to: #99751

Hi!

> - Can two objects can have the same object id
>   but different object handlers?
>   (e.g. iterators of some built in classes?)
>   I'm not familiar enough with PHP's history to be sure.

Yes, if extension using non-standard handlers is in use.

> - Can the the largest object handle be larger
>   than the size of `zend_long` in 32-bit systems?

Handle is uint32_t, so probably no.

-- 
Stas Malyshev
smalyshev@gmail.com

---

## #99755 — Nikita Popov — 2017-07-05T08:23:38+00:00

URL: https://externals.io/message/99751#99755 · In reply to: #99751

On Wed, Jul 5, 2017 at 2:01 AM, tyson andre <tysonandre775@hotmail.com>
wrote:

> There was a proposal back in 2015 to implement
> a function spl_object_id(object $o) : int`,
> which directly returns the object handle
> (similar to `spl_object_hash`, but as an integer, not a string).
> I'm interested in finishing implementing spl_object_id for php 7.2
>
> I already have working code implementing `spl_object_id()` at
> https://github.com/TysonAndre/php-src/pull/1
> The implementation XORs the object handle with the
> exact same random bits that `spl_object_hash` would.
>

You can drop the masking. It was never effective at what it's supposed to
do (hide memory addresses), but as this is the object ID only, it is
completely unnecessary here.


> Previous emails from 2015 can be seen here:
> - https://marc.info/?t=143835274500003&r=1&w=2
>
> Previous comment by a PHP maintainer in support of `spl_object_id()`
> - https://marc.info/?l=php-internals&m=143837339210596&w=2
>
> I'm unsure if an RFC is necessary. I have two pending questions.
>

I'm +1 on the addition and would be fine with including it without RFC, if
there are no objections on internals.


> - Can two objects can have the same object id
>   but different object handlers?
>   (e.g. iterators of some built in classes?)
>   I'm not familiar enough with PHP's history to be sure.
>

No: In PHP 7 this is not possible, which is also why `spl_object_hash()` no
longer includes the handlers.


> - Can the the largest object handle be larger
>   than the size of `zend_long` in 32-bit systems?
>

Only in the sense that it could theoretically wrap around to negative
numbers. Of course those would still serve as IDs just as well.


> Example places where this would be useful:
>
> 1. https://marc.info/?l=php-internals&m=143849841618494&w=2
>
> 2. I also recently wanted to track a large number of (cloneable)
>    small sets of objects in an application that sometimes used a lot of
> memory,
>    and the fact that arrays support copy on write helped save memory
>    relative to SplObjectHash if arrays and integer keys were used.
>    See https://github.com/etsy/phan/pull/729#issuecomment-299289378
>
> - Tyson Andre (tandre)

---

## #99756 — Anatol Belski — 2017-07-05T08:38:45+00:00

URL: https://externals.io/message/99751#99756 · In reply to: #99752

Hi,

> -----Original Message-----
> From: Stanislav Malyshev [mailto:smalyshev@gmail.com]
> Sent: Wednesday, July 5, 2017 5:28 AM
> To: tyson andre <tysonandre775@hotmail.com>; internals@lists.php.net
> Subject: Re: [PHP-DEV] Exposing object handles to userland
> 
> Hi!
> 
> > […]
> 
> Yes, if extension using non-standard handlers is in use.
> 
> > […]
> 
> Handle is uint32_t, so probably no.
> 
On 32-bit zend_long is a signed 32-bit int, so it can theoretically overflow, while sizeof is same.

Regards

Anatol

---

## #99776 — Stanislav Malyshev — 2017-07-05T20:21:35+00:00

URL: https://externals.io/message/99751#99776 · In reply to: #99755

Hi!

> No: In PHP 7 this is not possible, which is also why `spl_object_hash()` no
> longer includes the handlers.

Ah, I missed that part.

-- 
Stas Malyshev
smalyshev@gmail.com

---

## #99777 — Stanislav Malyshev — 2017-07-05T20:22:31+00:00

URL: https://externals.io/message/99751#99777 · In reply to: #99756

Hi!

> On 32-bit zend_long is a signed 32-bit int, so it can theoretically overflow, while sizeof is same.

Well, it's the same issue we having on representing any unsigned values,
I guess. Since int<->uint in this case is one-to-one, should be ok to
just use the negative nums, if they are used as IDs and not to calculate
anything, etc. So I don't think it's much of a problem here.

-- 
Stas Malyshev
smalyshev@gmail.com

---

## #99783 — tyson andre — 2017-07-06T05:23:18+00:00

URL: https://externals.io/message/99751#99783

Updated https://github.com/TysonAndre/php-src/pull/1 , which is now much shorter.

In response to Nikita Popov's comments:

> I'm +1 on the addition and would be fine with including it without RFC, if
> there are no objections on internals.

How long should I wait to see if there are objections before creating a pull request?

> > […]
> No: In PHP 7 this is not possible, which is also why `spl_object_hash()` no
> longer includes the handlers.

True. Checking again, the implementation of spl_object_hash
doesn't include the handlers, so I don't need to worry.

> You can drop the masking. It was never effective at what it's supposed to
> do (hide memory addresses), but as this is the object ID only, it is
> completely unnecessary here.
> [...]
> Only in the sense that it could theoretically wrap around to negative
> numbers. Of course those would still serve as IDs just as well.

That makes sense. I'm omitting the XOR
(and returning the unobfuscated object handle/id)
in the proposed change, then.

---

## #99787 — michal.brzuchalski@gmail.com — 2017-07-06T06:46:20+00:00

URL: https://externals.io/message/99751#99787 · In reply to: #99783

06.07.2017 07:24 "tyson andre" <tysonandre775@hotmail.com> napisał(a):
>
> Updated https://github.com/TysonAndre/php-src/pull/1 , which is now much
shorter.
>
> In response to Nikita Popov's comments:
>
> > […]
if
> > […]
>
> How long should I wait to see if there are objections before creating a
pull request?

AFAIK you can create PR any time.

>
> > […]
no
> > […]
>
> True. Checking again, the implementation of spl_object_hash
> doesn't include the handlers, so I don't need to worry.
>
> > […]
to
> > […]
>
> That makes sense. I'm omitting the XOR
> (and returning the unobfuscated object handle/id)
> in the proposed change, then.

---

## #99830 — tyson andre — 2017-07-11T04:59:52+00:00

URL: https://externals.io/message/99751#99830

> > […]
>AFAIK you can create PR any time.

I created a PR implementing spl_object_id(object $o) : int several days ago,
at https://github.com/php/php-src/pull/2611

---

## #99831 — Marco Pivetta — 2017-07-11T09:52:18+00:00

URL: https://externals.io/message/99751#99831 · In reply to: #99830

Asking here, since it's not clear to me: is this a good/fitting replacement
for `spl_object_hash()`?



> > […]
> pull request?
> > […]
>
> I created a PR implementing spl_object_id(object $o) : int several days
> ago,
> at https://github.com/php/php-src/pull/2611

---

## #99832 — Nikita Popov — 2017-07-11T10:21:48+00:00

URL: https://externals.io/message/99751#99832 · In reply to: #99831

> Asking here, since it's not clear to me: is this a good/fitting
> replacement for `spl_object_hash()`?
>
> 
>
> > […]
Yes. `spl_object_id()` provides the same guarantees as `spl_object_hash()` --
but is much faster and has a more compact output (an integer instead of an
iirc 32 byte string).

Nikita

---

## #99833 — Sara Golemon — 2017-07-11T11:01:09+00:00

URL: https://externals.io/message/99751#99833 · In reply to: #99751

> I'm unsure if an RFC is necessary. I have two pending questions.
>
Unless someone insists upon it, I'll put my release manager hat on and
say I'm fine with it just going in without an RFC.

-Sara

---

## #99837 — Benjamin Eberlei — 2017-07-11T16:44:27+00:00

URL: https://externals.io/message/99751#99837 · In reply to: #99832

> On Tue, Jul 11, 2017 at 11:52 AM, Marco Pivetta <ocramius@gmail.com>
> wrote:
>
> > […]
> Yes. `spl_object_id()` provides the same guarantees as `spl_object_hash()` --
> but is much faster and has a more compact output (an integer instead of an
> iirc 32 byte string).
>

Just to clarify, that means object ids are still re-used between objects if
one gets destroyed? The initial bug report was about creating a second
function that solves this problem.

>
> Nikita

---

## #99845 — tyson andre — 2017-07-11T20:56:36+00:00

URL: https://externals.io/message/99751#99845

> Just to clarify, that means object ids are still re-used between
> objects if one gets destroyed? 
> The initial bug report was about creating a second function that solves this problem.   

Correct. This is intended to return the object handles.
The most recent discussion from 2015 was only about object handles.
An intended side effect is that object ids are re-used, the same way spl_object_hash is reused.

- i.e. this is not intended to solve https://bugs.php.net/bug.php?id=52657 , and NEWS should not link to that bug id.

Having unique integers wouldn't work as an integer in long runs of processes 32-bit builds
- After ~4 billion objects were constructed, the 32-bit integer would be reused.

As for a globally unique object id (let's call that spl_object_uuid),
I don't think it'll ever get included.
I also don't have any need for it.

- It would require adding an additional field to zend_object,
  which would hurt performance and increase overall memory usage 
  (e.g. increasing 64-bit integer)
- No other programming languages I'm aware of have that 
  (globally unique object id, even after object is garbage collected)
  as a native feature.
