Hi Pedro, You articulated your problem well. Thanks.
If you have a need to use a container so that it must return a shared or new instance than using the PSR-11 interface directly is not a solution. Just as everyone said, PSR-11 is not addressing this problem. I said this another time in another thread: Having in mind the fact that you can't rely on obtaining a shared/new instance from the container, can you still use the PSR-11 interface? My answer is yes, considering some practiced that people might say are good practices anyway: Use the container to inject stateless services only. Use as much as possible only stateless services so that you will need only one instance of it in a php process. You should separate state: value objects should be different class than service objects. Value object keep state, service objects execute logic using state as state as input/output. If you really need to have a service with state, don't inject it directly but inject the stateless service object that can give you the instance you need. That is a factory in case you always need to create a new instance or is a registry in case you need a multiton pattern or a singletons wrapper in case you really need to be sure you are using the same instance like for an event manager. So you see, you can build some tools to wrap a PSR-11 interface. You will not use it directly for all cases but probably there won't be so many cases where you have non-stateless services if you try to do it. This is how I use the container-interop interface and it's working. Anyway, you should build your classes agnostics of PSR-11. Only the "application" classes will use it to wire things up. Hope I was helpful with my point of view. Regards, Alex On Tue, Nov 8, 2016 at 2:55 PM, Pedro Cordeiro <[email protected] > wrote: > Hi, Matthew! > > I understand everything you said. About the configuration responsibility, > this PSR's scope and the fact that it's coherent to have non-shared > services in some contexts. I never disagreed with any of that. > > I'll try to be more objective here. > > Given two containers: > > a) "ContainerShared", that implements PSR-11 and ONLY returns shared > instances, no option to configure non-shared services; > b) "ContainerFactory", that implements PSR-11 and ONLY returns non-shared > instances, acts as a factory always. > > Do you agree that: > > 1) These implementations are perfectly fine PSR-11 implementations, as > it's phrased right now? > 2) These implementations are incompatible between themselves for pretty > much every use case, including zend-expressive, that is currently the most > successful case of container interoperability? > 3) The incompatibility between these two containers is not an > application/configuration issue, but plain lack of interoperability between > them? > > If you agree with (1), (2) and (3), the final question that stands is: is > it still OK to have container implementations that are NOT interoperable > implementing an interoperability standard? > > I understand zend-servicemanager is a coherent implementation, that allows > for both shared and non-shared services, and that configuring which > services are shared is up to the application. I don't disagree. > I understand that most current container implementations allow for both > kinds of services, shared and non-shared, and that it'd be up to the > application to configure which is which. I don't disagree. > > But certain implementations (as presented above) could still be 100% > incompatible for its consumers - not because *I*, the application > developer, configured something wrong (a bug), but because the *CONSUMING* > standard (PSR-11) simply allows for non-interoperable container > implementations. > > If *YOU*, zend-expressive developer, were to develop a truly agnostic > container consumption implementation based on PSR-11, you'd have to > document something to the effect of: "while zend-expressive is compatible > with PSR-11 containers in general, it's not meant to be used with > factory-only containers. Choose accordingly.". THAT is what strikes me as > something weird to have. > > I'd choose (3) over (1), but (1) is better than (2). Enforce shared-only > services or allow shared/exclusive services to coexist, explicitly > disallowing factory-only implementations. If you can't do either, having > factory-only containers should be highly discouraged on the META document > and the standard shouldn't even mention the possibility of having > non-shared services (even though it'd allow by omission). > > If you disallow factory-only implementations, you can truly blame the > application configuration for any misuse of the container. But if you allow > factory-only implementations to coexist with shared-only implementations, > you end up with a non-interoperable interoperability standard. > > 2016-11-07 21:34 GMT-02:00 Matthew Weier O'Phinney < > [email protected]>: > >> On Fri, Nov 4, 2016 at 7:55 PM, Larry Garfield <[email protected]> >> wrote: >> > Pedro did a fine job of explaining the sort of use case where I'd >> expect to >> > see potential issues with a lack of clarity about whether a service is >> > shared or not. Frankly I don't find the "out of scope" argument to be >> > compelling; I as a consumer care, therefore it is in scope to me as a >> > consumer. >> > >> > The only compelling argument I've seen so far is the BC issue for >> existing >> > container implementations, which is a valid consideration. >> > >> > To that end, I'd prefer to get input from Fabien and Taylor, as David >> > suggests, before weighing in on the listed options. >> >> I'll weigh in, as we're a project that provides a concept of shared vs >> unshared services. >> >> zend-servicemanager shares services by default. That's the expected >> use case 99% of the time. However, there are occasionally services you >> may not want to share, and for that we have the ability to mark >> services as *not* shared. One example already raised in this thread is >> event manager instances; these are specific to each service composing >> them, but are themselves injected with a shared event manager instance >> for sharing listeners across event manager instances. >> >> Another situation is with some of our plugins: validators, filters, >> etc. that may be stateful, and require separate instances as many >> instances with different configuration may be in play. >> >> From a consumer perspective, this is something *you* are in control >> of. It is something specific to *your* application, where *you* have >> made the decision of what container you are using, and thus have >> control over the *configuration* of it. >> >> From a practical standpoint, consider Expressive. We provide >> functionality for setting up three different container implementations >> currently: Aura.Di, Pimple, and zend-servicemanager. We provide some >> functionality for bridging configuration between them in the file that >> creates the container instance. But final application configuration >> and container configuration *is up to you, the developer*. >> >> So far, it's not posed any problems. If you do not want an instance >> shared, you configure it that way. >> >> From the *API* perspective, it doesn't matter, because the code that >> consumes the container is only exercising the container-interop API, >> and assumes that *you*, the developer, have configured the container >> the way you need to. >> >> As such, I totally agree with the statement that whether or not the >> instance returned by get() is shared or not is out of scope; that's in >> scope for a PSR that details *configuring* a container, as the point >> at which you decide whether or not an instance is shared is during >> configuration, not *consumption*. PSR-11 is about *consuming* services >> from a container. >> >> >> > On 11/04/2016 12:19 PM, Pedro Cordeiro wrote: >> > >> > Hi, David. >> > >> > Thank you again for your response. >> > >> > I understand your point of view. You don't think there is anything the >> ORM >> > should do to prevent fetching a non-shared instance, because that would >> be >> > the responsibility of the application. I kind of agree, to a limited >> scope. >> > >> > But if you allow me to press on this issue just a little longer... it >> still >> > doesn't change the fact that I can still have two different containers: >> > ContainerShared, that only configures/fetches shared services, and >> > ContainerFactory, that only fetches new instances. They would both be >> PSR-11 >> > compliant, and still, incompatible for most cases. And then, it >> wouldn't be >> > a configuration issue (a bug) on the application end, it would be a >> > component incompatibility - which kind of defeats the point of having a >> > interoperability standard. It'd still be a little odd saying something >> like >> > "this ORM can be used with PSR-11 compatible containers, except for >> > containers that don't have the option to configure shared services (like >> > ContainerFactory)". >> > >> > Choosing a standardized component is not a configuration bug, right? >> Should >> > we let two PSR-11 implementations be incompatible for many (if not most) >> > cases, in the name of backwards compatibility (with containers that >> still >> > don't extend PSR-11)? >> > >> > You tell me this concern is out of scope. I don't disagree. I'm just >> saying >> > that, IMO, the current scope is not enough to assure two different >> > implementations are actually compatible - and thus, interoperable, >> which is >> > kind of the point here. And there is something we could do to fix this, >> > without broadening the scope -- limit what kind of services (shared or >> > exclusive) "get" can return. This leads us to a different issue, which >> is >> > compatibility with current implementations. >> > >> > To be completely honest here, with best practices in mind, I can't even >> > think of why a framework component (the ORM, in this case) should even >> be >> > container-aware. It should have its dependencies declared directly in >> the >> > constructor (or in separate setters) and just trust someone else (the >> > application) will inject them. A container should be just one of the >> > framework's components, not part of its core/kernel. >> > >> > Em sexta-feira, 4 de novembro de 2016 13:45:29 UTC-2, David Négrier >> > escreveu: >> >> >> >> Hi Pedro, >> >> >> >> I understand your example (about the event dispatcher that MUST be >> >> shared), but still, I disagree this is an issue with PSR-11. >> >> >> >> You say: >> >> >> >> Now, my consumer, the ORM, is completely container agnostic. It only >> >> works, however, with SOME specific implementations (that ALWAYS return >> >> shared instances), and fails on SOME others (that ALLOWS for >> factories). I >> >> don't know (and can't control) how the entries were set, because I >> deferred >> >> this wiring to the application realm, by design. I don't know (and >> can't >> >> control) which container this is. If I can't guarantee it will work >> with ANY >> >> PSR-11 implementation, I cannot depend on the contract (PSR-11) - I'll >> have >> >> to depend of an implementation, which is bad. >> >> >> >> When you say: It only works, however, with SOME specific >> implementations >> >> (that ALWAYS return shared instances), and fails on SOME others (that >> ALLOWS >> >> for factories), I disagree. If we use "solution 3" I'm proposing >> above, you >> >> should really write: It only works, however, with SOME specific >> >> configurations (that ALWAYS return shared instances), and fails on SOME >> >> others (for containers that CAN provide non-shared services and that >> have >> >> been configured accordingly) >> >> >> >> Now, you say: I don't know (and can't control) how the entries were >> set, >> >> because I deferred this wiring to the application realm, by design. >> >> >> >> When you say "I", I suppose you mean "the ORM author", am I right? Of >> >> course, you are right to say the ORM author can't control if the event >> >> dispatcher is shared or not. And it is not its job. And I'm sure you >> agree >> >> with me if I say that the ORM is not using ContainerInterface directly >> (it >> >> is the container how creates the ORM's EntityManager and injects the >> event >> >> dispatcher in it. >> >> >> >> So in the end, the wiring of the app is deferred to the application >> realm >> >> (i.e. the end user). If the end user badly screws up its configuration >> and >> >> decides to configure a non-shared event dispatcher, that's its problem >> (it's >> >> a bug), not a problem with PSR-11. Of course, with a more restrictive >> PSR-11 >> >> (that would force shared services only), this kind of bug would not be >> >> possible. But we loose compatibility with all the containers out there >> and >> >> it's just not worth it in my opinion. >> >> >> >> Finally, we will inevitably end up working on a PSR that defines how we >> >> put things in a container. In this PSR, we will need to be very strict >> >> regarding the fact that we set a shared or a non-shared service. >> >> If you haven't done so yet, you should definitely take a look at >> >> container-interop/service-provider. This project proposes a way to put >> >> things into a container (and I hope will be the basis of a future >> PSR). I >> >> just submitted a PR (here: >> >> https://github.com/container-interop/service-provider/pull/33/files) >> that >> >> makes sure that containers consuming a service provider MUST provide >> shared >> >> services. So even if PSR-11 allows for non-shared service, >> >> container-interop/service-provider explicitly forbids it for services >> >> provided in service providers. >> >> >> >> TL;DR; I understand your sample about the event dispatcher being a >> >> non-shared service. This would definitely be an issue. I just disagree >> that >> >> it is a concern with PSR-11. It is a concern with either the user >> >> configuring the container, or the next PSR to come that defines how we >> put >> >> things into a container. >> >> >> >> Does it make more sense? >> >> >> >> ++ >> >> David. >> >> >> >> >> >> Le jeudi 3 novembre 2016 10:58:51 UTC+1, Pedro Cordeiro a écrit : >> >>> >> >>> > The typical use case for ContainerInterface is to allow a consumer >> >>> > (like a router) to be "container agnostic". >> >>> >> >>> I completely agree. I can't think of a use case where a router would >> >>> depend on having either shared instances or exclusive instances of a >> >>> controller, so I'll change this example a little. Hopefully this >> answers >> >>> @Matthieu's question too. >> >>> >> >>> Let's say I have a framework component (and ORM, maybe) that triggers >> >>> events (to log queries, maybe). This part of my framework fetches an >> event >> >>> dispatcher (let's say, symfony's) from the registry, and it HAS to be >> a >> >>> shared entry (otherwise, I'll just dispatch an event on a new >> instance that >> >>> has no listeners). >> >>> >> >>> Now, my consumer, the ORM, is completely container agnostic. It only >> >>> works, however, with SOME specific implementations (that ALWAYS return >> >>> shared instances), and fails on SOME others (that ALLOWS for >> factories). I >> >>> don't know (and can't control) how the entries were set, because I >> deferred >> >>> this wiring to the application realm, by design. I don't know (and >> can't >> >>> control) which container this is. If I can't guarantee it will work >> with ANY >> >>> PSR-11 implementation, I cannot depend on the contract (PSR-11) - >> I'll have >> >>> to depend of an implementation, which is bad. >> >>> >> >>> The only instances where I could depend on a 100% generic PSR-11 >> >>> container is when I don't care at all if the service being retrieved >> is >> >>> exclusive or shared. And there only needs to be ONE place where I >> need a >> >>> specific kind of instance, and my entire framework will depend on a >> specific >> >>> implementation. The event dispatcher service is one example where I >> need a >> >>> shared instance -- the ORM could be another. I don't want new >> connections >> >>> being opened, I don't want two separate units of work with two >> different >> >>> in-memory caches. If I fetch my ORM twice from the container, I >> expect to be >> >>> given the same instance, not two different separate instances. If I >> fetch it >> >>> twice from separate consumers, I still expect to be given the same >> instance. >> >>> >> >>> Now, I'll reiterate that I understand strengthening the SHOULD to a >> MUST >> >>> would greatly hinder this PSR's adoption. I just want to know if you >> guys >> >>> understand my point and if you guys still disagree that this is an >> issue, >> >>> and why. I don't know if I'm failing to see it, but as far as I can >> think >> >>> about it, not knowing what kind of instance the container will yield >> would >> >>> also greatly restrict the possible uses and hinder its adoption -- >> and I'm >> >>> not even talking about things out of scope here, because I'm failing >> to see >> >>> its usefulness even for consumer-only frameworks, like shown on the >> previous >> >>> examples. >> >>> >> >>> Em quarta-feira, 2 de novembro de 2016 15:45:49 UTC-2, David Négrier >> >>> escreveu: >> >>>> >> >>>> This is a continuation from the discussion about whether PSR-11 >> >>>> containers should always return the same instance. >> >>>> See https://groups.google.com/forum/#!topic/php-fig/L8rDUwRFsOU for >> the >> >>>> beginning of the discussion. >> >>>> >> >>>> <TL;DR;> I believe that we should keep the SHOULD word in place >> because >> >>>> it does not hurt in practice and because we can require a container >> to >> >>>> always return the same instance in the yet to come PSR that will >> define how >> >>>> we put things into a container (see container-interop/service-provider >> for a >> >>>> proposal). On the other hand, requiring the container to return >> always the >> >>>> same value would make PSR-11 de-facto incompatible with most >> containers out >> >>>> there (so should be avoided). However, I think we definitely need to >> make >> >>>> improvements on the wording that is clumsy (see end of the message). >> >>>> </TL;DR;> >> >>>> >> >>>> Currently, the spec says: >> >>>> >> >>>> Two successive calls to get with the same identifier SHOULD return >> the >> >>>> same value. However, depending on the implementor design and/or user >> >>>> configuration, different values might be returned, so user SHOULD >> NOT rely >> >>>> on getting the same value on 2 successive calls. >> >>>> >> >>>> Hari, Larry, Pedro are asking if we could strengthen the SHOULD to a >> >>>> MUST (as in: Two successive calls to get with the same identifier >> MUST >> >>>> return the same value). >> >>>> >> >>>> For instance, Larry says: >> >>>> >> >>>> > I would prefer to have get() defined to always return the same >> object >> >>>> > (lazy loaded or otherwise, not relevant here), as that is the >> typical case, >> >>>> > and another method added (either on the same interface or a >> separate one, I >> >>>> > am flexible) to handle the factory use case. That way I know the >> behavior >> >>>> > of each object I get back, specifically in relation to whether I >> have a >> >>>> > private copy or not. >> >>>> >> >>>> First of all, let me say if I was starting from a blank slate, I >> would >> >>>> definitely agree with you and put a MUST here. But we are not >> starting from >> >>>> a blank slate and many containers out there offer the possibility to >> create >> >>>> new services each time you call "get". For instance Pimple (with the >> factory >> >>>> method), or Symfony (with the "shared" option: >> >>>> http://symfony.com/doc/current/service_container/shared.html) >> >>>> I definitely want Pimple and Symfony in PSR-11 (or at least I want >> to be >> >>>> able to create an adapter for those) and putting a "MUST" in the >> >>>> requirements makes this impossible. So if we decide to force >> containers to >> >>>> always return the same value, we'd better have a very good reason to >> do so. >> >>>> >> >>>> Now, what is the real impact of this? >> >>>> >> >>>> You all seem to imply that if we don't put a "MUST" here, then we >> cannot >> >>>> "trust" the container to give us a usable instance. The container >> might be >> >>>> "vicious" and decide to fool its user by giving him a new instance >> while the >> >>>> user was expecting the same instance. But this is not how it works. >> The >> >>>> typical use case for ContainerInterface is to allow a consumer (like >> a >> >>>> router) to be "container agnostic". As a user, I can decide to plug >> any >> >>>> container to a given router. The router will then be able to fetch >> the >> >>>> correct controller (or the correct action if you do ADR) based on the >> >>>> controller name. In this scenario, the user is the one in charge of >> >>>> configuring the container (and putting the controller in the >> container). If >> >>>> the user decides that he wants to use a container that can act as a >> factory >> >>>> and that he wants to configure some services that are created on each >> >>>> request, it is his responsibility. Keep in mind that since we do not >> >>>> standardize how to put things in the container, it has to be the user >> >>>> responsibility to configure his container. >> >>>> >> >>>> So saying that a container MUST return always the same instance is >> >>>> premature. When we will start to standardize how to put things in a >> >>>> container, then we can define that configured instances MUST be the >> same. >> >>>> But we can do this in the next PSR (the one that defines how to put >> things >> >>>> into a container) and not in this one. >> >>>> >> >>>> >> >>>> Now, even if I'm really convinced that we should keep the "SHOULD" in >> >>>> place, I understand from the numerous comments that the way the spec >> is >> >>>> written is clumsy (or rather worrisome). >> >>>> >> >>>> Why did I propose this sentence in the first place? I was thinking >> that >> >>>> a "CompositeContainer" could try to cache in an array the list of >> services >> >>>> already fetched from its children. This is something you can do if >> you know >> >>>> the children containers will always return the same instance but >> that you >> >>>> cannot do if you don't know if the container will return the same or >> a new >> >>>> instance. So really, the "SHOULD" prevents us to write composite >> containers >> >>>> that "cache" the result from children. This is actually not a very >> big deal, >> >>>> as composite containers are very seldomly used. What I was trying to >> say >> >>>> here was: "Hey, don't cache the services returned by a container, it >> might >> >>>> return a new instance on the next call". I proposed this wording 2 >> years ago >> >>>> in container-interop. In hindsight, this is certainly too specific >> to be >> >>>> part of a PSR. >> >>>> >> >>>> I see 3 possible solutions to replace this: >> >>>> >> >>>> Solution 1: >> >>>> Let's completely drop the 2 sentences => PSR-11 does not address >> whether >> >>>> a container should return the same instance or not (this is >> something we can >> >>>> deal with when we define how to put things into a container) >> >>>> >> >>>> Solution 2: >> >>>> Let's only keep the first sentence: Two successive calls to get with >> the >> >>>> same identifier SHOULD return the same value. >> >>>> >> >>>> Solution 3: >> >>>> Let's rewrite the second sentence: Two successive calls to get with >> the >> >>>> same identifier SHOULD return the same value. A container MAY offer >> the >> >>>> possibility to return a new value for some identifiers if the user >> >>>> configured it accordingly. >> >>>> (The wording of solution 3 should be improved but you get the idea) >> >>>> >> >>>> @larry, @hari, @pedro: do you favor one of those solutions or do you >> >>>> still think we should use a "MUST" in the spec? >> >>>> @matthieu, @mathew: any preference regarding the solutions proposed >> >>>> above? >> >>>> >> >>>> We should also try to ping more container authors to get their >> advice on >> >>>> this issue. I'd be interested in knowing what Fabien Potencier or >> Taylor >> >>>> Otwell think about this. >> >>>> >> >>>> ++ >> >>>> David >> > >> > -- >> > >> > -- >> > You received this message because you are subscribed to the Google >> Groups >> > "PHP Framework Interoperability Group" group. >> > To unsubscribe from this group and stop receiving emails from it, send >> an >> > email to [email protected]. >> > To post to this group, send email to [email protected]. >> > To view this discussion on the web visit >> > https://groups.google.com/d/msgid/php-fig/8711ead1-3aa7-d9e4 >> -caad-04852cf2338f%40garfieldtech.com. >> > >> > For more options, visit https://groups.google.com/d/optout. >> >> >> >> -- >> Matthew Weier O'Phinney >> [email protected] >> https://mwop.net/ >> >> -- >> You received this message because you are subscribed to the Google Groups >> "PHP Framework Interoperability Group" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> To post to this group, send email to [email protected]. >> To view this discussion on the web visit https://groups.google.com/d/ms >> gid/php-fig/CAJp_myVztpuKK0vDdJNXkvMqVcXCp84PitP%3DMt_vuNy1% >> 2Bhbv4g%40mail.gmail.com. >> For more options, visit https://groups.google.com/d/optout. >> > > > > -- > > *Pedro Cordeiro* > Produto > > Phone: +55 31 3024 1115 > <%2B55%2031%203024%200283> > > [image: Logo assinatura] > <http://t.rdsv6.net/wf/click?upn=9ID9MxPkUk-2FXCePkr1qGk3jeNsyS6MabLki1WEC2jiXwUuwMLrMuwyQMihLilvGuFQlwqGcwaqcxv14TZBo-2Fkx216CWkoFS-2BFrkKrfuwK-2BVQHJQ1z2pKo2dYIxq5cmilGdRu7bAh5za9wh3RLzO4nA-3D-3D_wKmGSCWlO-2F6J-2FSpm-2BxtvG5JaaAosDe4Q3OV4TyR4tzwOAocQ0H-2BKup9nj5ZrffTGmoFTZ-2FwY-2BiZ62zA9YUETNc69y4PsViv5cHctzYQM9bh8n4o9ivPlzVyx-2BJyllIEnG1Q-2F2tN-2BOSPuz0Nn8uv2ZSfKxBLUbTLKbmGhzSIZRi0PYxNI8DwJc7HKhR0hHwKI8kmuyZfBkzNrxoCmV0NXGSkn3a3WzIqMEkuwdILSgR-2Fm4Yi08v1XJ0ACOgxAjO-2BND8H30UmwWPAPr6joAP3kKuQ6WcA7R-2FTErDPH0l26ly5T8d00DrbMV7fXYAiuL24XcUrHvHs1-2BIk0UWwDs-2F72MMLfB2NOFl6lJHtovPskkuiwYJajeWEJycLVSCkLape6k6LHU-2BSZcF2Uvp2Asye0iUJTldf0eVlnrql-2BA6I-2F6d00ZAiOxLHEVlUTd1ixtgJipaRe0L1jjobMF41uBNJLCRzafhz8q5oziitdm7z7VLEgrZz2klJhql8ltu8q97TK> > > > <http://t.rdsv6.net/wf/click?upn=9ID9MxPkUk-2FXCePkr1qGk3jeNsyS6MabLki1WEC2jiXwUuwMLrMuwyQMihLilvGuFQlwqGcwaqcxv14TZBo-2Fkx216CWkoFS-2BFrkKrfuwK-2BVQHJQ1z2pKo2dYIxq5cmilGdRu7bAh5za9wh3RLzO4nA-3D-3D_wKmGSCWlO-2F6J-2FSpm-2BxtvG5JaaAosDe4Q3OV4TyR4tzwOAocQ0H-2BKup9nj5ZrffTGmoFTZ-2FwY-2BiZ62zA9YUETNc69y4PsViv5cHctzYQM9bh8n4o9ivPlzVyx-2BJyllIEnG1Q-2F2tN-2BOSPuz0Nn8uv2ZSfKxBLUbTLKbmGhzSIZRi0PYxNI8DwJc7HKhR0hHwKI8kmuyZfBkzNrxoCmV0NXGSkn3a3WzIqMEkuwdILSgR-2Fm4Yi08v1XJ0ACOgxAjO-2BND8H30UmwWPAPr6joAP3kKuQ6WcA7R-2FTErDPH0l26ly5T8d00DrbMV7fXYAiuL24XcUrHvHs1-2BIk0UWwDs-2F72MMLfB2NOFl6lJHtovPskkug8HnNMYMLjg6qWS45zCOIrm0vptTNigLUcaaUyHWLPOZGe0FSmf9PqyBfjwjFw-2F88h7bt2F1L5K-2FcCWvoYbYXvfmpn1s4vRjzgBFGFfMaV4wNfAKPCaPqR75Md-2Flsd-2F7ry86VRGQ2Sc0YQoNvf1REv>*O > site com o maior número de eventos à venda do Brasil!* > > <http://t.rdsv6.net/wf/click?upn=9ID9MxPkUk-2FXCePkr1qGk3jeNsyS6MabLki1WEC2jiXwUuwMLrMuwyQMihLilvGuFQlwqGcwaqcxv14TZBo-2Fkx216CWkoFS-2BFrkKrfuwK-2BVQHJQ1z2pKo2dYIxq5cmilGdRu7bAh5za9wh3RLzO4nA-3D-3D_wKmGSCWlO-2F6J-2FSpm-2BxtvG5JaaAosDe4Q3OV4TyR4tzwOAocQ0H-2BKup9nj5ZrffTGmoFTZ-2FwY-2BiZ62zA9YUETNc69y4PsViv5cHctzYQM9bh8n4o9ivPlzVyx-2BJyllIEnG1Q-2F2tN-2BOSPuz0Nn8uv2ZSfKxBLUbTLKbmGhzSIZRi0PYxNI8DwJc7HKhR0hHwKI8kmuyZfBkzNrxoCmV0NXGSkn3a3WzIqMEkuwdILSgR-2Fm4Yi08v1XJ0ACOgxAjO-2BND8H30UmwWPAPr6joAP3kKuQ6WcA7R-2FTErDPH0l26ly5T8d00DrbMV7fXYAiuL24XcUrHvHs1-2BIk0UWwDs-2F72MMLfB2NOFl6lJHtovPskkuh-2FcAWngEps85gZcv1JSt88f2MW6opGq90KNlySvzdU-2Fye89UtpBfv3fUye6Q18GdWjcQkrSLGREh4GUTjQXGm2TY6JDX6BMrWAmqiU-2BRatDqBDMb7o4f0IPHrMBwqWCmc1qGopJBiN5-2FLRBjhg40Gq> > www.sympla.com.br > <http://t.rdsv6.net/wf/click?upn=9ID9MxPkUk-2FXCePkr1qGk3jeNsyS6MabLki1WEC2jiVLI3wuhL5Ti6hw89C0ESCSVJNdh8FfaGqV-2BFmL5HRlzZKExa4qrB0ctNsViB6l8TFdI11l371V56-2Ffz1iwPM-2FaLxM6A0XQGU-2B6JVEDbnNA0Q-3D-3D_wKmGSCWlO-2F6J-2FSpm-2BxtvG5JaaAosDe4Q3OV4TyR4tzwOAocQ0H-2BKup9nj5ZrffTGmoFTZ-2FwY-2BiZ62zA9YUETNc69y4PsViv5cHctzYQM9bh8n4o9ivPlzVyx-2BJyllIEnG1Q-2F2tN-2BOSPuz0Nn8uv2ZSfKxBLUbTLKbmGhzSIZRi0PYxNI8DwJc7HKhR0hHwKI8kmuyZfBkzNrxoCmV0NXGSkn3a3WzIqMEkuwdILSgR-2Fm4Yi08v1XJ0ACOgxAjO-2BND8H30UmwWPAPr6joAP3kKuQ6WcA7R-2FTErDPH0l26ly5T8d00DrbMV7fXYAiuL24XcUrHvHs1-2BIk0UWwDs-2F72MMLfB2NOFl6lJHtovPskkuhalNGqZenIN2ujgLDSs5Ohlft6K9qJu5v-2FZ3QUR1aZ9-2FzqGgwzr01AaKq7A-2FhO998bW0GWIpli0JgybJylzgA2ITDrio-2FSPnUvfYn56sgyWGIEtX1JTsSWBKJ7DZK8go8mcVbmwvX2oitsQJ8jGzKm> > > -- > You received this message because you are subscribed to the Google Groups > "PHP Framework Interoperability Group" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To post to this group, send email to [email protected]. > To view this discussion on the web visit https://groups.google.com/d/ > msgid/php-fig/CADuw3E8UDnXWJ5WHQ6ES_JQuSMx1YeVLY_1EWCDXKWVgy2fvsg% > 40mail.gmail.com > <https://groups.google.com/d/msgid/php-fig/CADuw3E8UDnXWJ5WHQ6ES_JQuSMx1YeVLY_1EWCDXKWVgy2fvsg%40mail.gmail.com?utm_medium=email&utm_source=footer> > . > > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/CAAwdEzDM92zv%3DC2u9zrx%3D-24-OMF6SedqB1h9aWuL%2BOZ1tLPkw%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
