Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Phalcon\Registry #1935

Merged
merged 9 commits into from Jan 31, 2014
Merged

Phalcon\Registry #1935

merged 9 commits into from Jan 31, 2014

Conversation

ghost
Copy link

@ghost ghost commented Jan 28, 2014

See #1209

A registry is a container for storing objects and values in the application space. By storing the value in a registry, the same object is always available throughout the application.

In addition to ArrayAccess, Phalcon\Registry implements ArrayAccess, Countable, Serializable and Iterator interfaces. For PHP 5.4 and higher, JsonSerializable interface is implemented.

Phalcon\Registry is very fast (it is typically faster than any userspace implementation of the registry); however, this comes at a price: Phalcon\Registry is a final class and cannot be inherited from.

Though Phalcon\Registry exposes methods like __get(), offsetGet(), count() etc, it is not recommended to invoke them manually (these method exists mainly to match the interfaces the registry implements): $registry->__get('property') is several times slower than $registry->property.

Internally all the magic methods (and interfaces except JsonSerializable) are implemented using object handlers or similar techniques: this allows to bypass relatively slow method calls.

@ovr
Copy link
Contributor

ovr commented Jan 28, 2014

Good idea.

@ghost
Copy link
Author

ghost commented Jan 29, 2014

Benchmark results: Phalcon\Registry vs class Registry {}, 5,000,000 iterations:

Read Test ($var += $registry->test)

  • Phalcon: 1.562s
  • Userspace: 1.700s

Read Test via explicit __get()

  • Phalcon: 5.459s
  • Userspace: 1.652s

Read Test using References ($a = &$registry->test)

  • Phalcon: 1.618s
  • Userspace: 1.781s

Read Test (using ArrayAccess interface)

  • Phalcon: 1.516s
  • Userspace: 1.644s

Write Test ($registry->member = $variable)

  • Phalcon: 2.372s
  • Userspace: 2.377s

Write Test (ArrayAccess)

  • Phalcon: 2.387s
  • Userspace: 2.392s

@jymboche
Copy link
Contributor

Question... Is this much different than Phalcon\Config? If so, how? I haven't used Phalcon much yet, but it seems like Phalcon\Config is somewhat used as a registry.

@ghost
Copy link
Author

ghost commented Jan 29, 2014

@jymboche Yes, they are similar, however, there are a few differences:

  1. Phalcon\Config may modify the data it is given — for example, it recursively converts all arrays to Phalcon\Config objects
  2. Registry is faster — it is optimized for fast reads/writes

@ghost
Copy link
Author

ghost commented Jan 30, 2014

With the latest optimizations (f2130da):

Read Test

  • Phalcon: 1.508s
  • Userspace: 1.712s

Read Test (__get())

  • Phalcon: 5.690s
  • Userspace: 1.667s

Read Test (reference)

  • Phalcon: 1.528s
  • Userspace: 1.779s

Read Test (ArrayAccess)

  • Phalcon: 1.529s
  • Userspace: 1.660s

Write Test

  • Phalcon: 2.301s
  • Userspace: 2.374s

Write Test (ArrayAccess)

  • Phalcon: 2.382s
  • Userspace: 2.426s

phalcon pushed a commit that referenced this pull request Jan 31, 2014
@phalcon phalcon merged commit d00649b into phalcon:1.3.0 Jan 31, 2014
@ghost ghost deleted the registry branch January 31, 2014 22:45
@temuri416
Copy link
Contributor

@sjinks

Having just recompiled Phalcon v1.3.0 I have started running into this:

Phalcon\DI\Service::resolve(): Usage of Phalcon\DI to store non-objects is deprecated, please use Phalcon\Registry instead 

I am using Phalcon\Di to set Closures that perform certain tasks. Sometimes, the result of ->resolve() would be an initialized class (like GoogleDrive service), sometimes it would be a JSON string that's a result of DB fetch and post-processing. Having initialized GoogleDrive service class once and having created a JSON string I could access them multiple times within the lifetime of a request.

And it worked great.

OK, I could split my DI and move closures returning stings into Phalcon\Registry. However, I cannot set a Closure as registry value to later invoke it:

$reg = new Phalcon\Registry;

$reg->reverse = function($el) {
    return strrev($el);
};

I could revisit all my DI closures, make them set Phalcon\Registry keys and return new \stdClass from those that used to return strings. But, that would suck big time.

What's the harm in allowing to return strings, anyway?

I am hoping that there's a way out of this and I won't have to rewrite two thirds of my app......... :(

Thanks.

@temuri416 temuri416 mentioned this pull request Feb 26, 2014
@phalcon
Copy link
Collaborator

phalcon commented Feb 26, 2014

Why you can't invoke the closure in the Registry?

$str = $reg->reverse();

@temuri416
Copy link
Contributor

Because of this:

echo $reg->reverse('zxcv');

PHP Fatal error:  Call to undefined method Phalcon\Registry::reverse()

@temuri416
Copy link
Contributor

But even if that worked - I think that Phalcon\Di error (that's generated when a string is returned) must be deprecated.

@ghost ghost mentioned this pull request Feb 27, 2014
@ghost
Copy link
Author

ghost commented Feb 27, 2014

Because of this:

Added that in #2105

@temuri416
Copy link
Contributor

@sjinks @phalcon

Thanks!

Can that DI error be removed, please?

See my comment here:
#1209 (comment)

@pdeszynski
Copy link
Contributor

An awful idea. A registry is a global static object that moves through whole app. This component will make a lot of code untestable and generally should not exist (it was HUGE pain in ZF1 and was removed in ZF2). I don't understand either idea of putting closures into a registry. Would be the same as making them global, named functions.

@temuri416
Copy link
Contributor

Fortunately, @phalcon has removed commented out throwing error on strings in DI. Lord be praised.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants