Skip to end of metadata
Go to start of metadata

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

<h1><ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[Zend_Bitfield]]></ac:plain-text-body></ac:macro> Proposal Review</h1>

<ac:macro ac:name="info"><ac:parameter ac:name="title">Work in Progress</ac:parameter><ac:rich-text-body>
<p>This proposal has entered incubation. Feedback, ideas, use cases, implementation suggestions, and design input are welcomed. If you see a potential problem, please don't wait until this component is released before responding. You may enter comments directly at the end of the document, or for more directed comments you may <a><ac:plain-text-body><![CDATA[10013]]></ac:plain-text-body>">create a new issue</a> in the issue tracker for this project.</p>

<p>For developer notes and discussions of design and implementation issues, please see: <a><ac:plain-text-body><Unable to render embedded object: File (plain-text-body>" class="external-link">http://framework.zend.com/wiki/display/ZFDEV/<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><) not found.[CDATA[Zend_Bitfield]]></ac:plain-text-body></ac:macro></a></p></ac:rich-text-body></ac:macro>

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[]]></ac:plain-text-body></ac:macro>
<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

]]></ac:plain-text-body></ac:macro>

<ac:macro ac:name="include"><ac:default-parameter>ZFDEV:Zend Proposal Zone Template</ac:default-parameter></ac:macro>

]]></ac:plain-text-body></ac:macro>

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Jun 20, 2006

    <p>Couple items.</p>

    <p>Instead of an array for the perm types I suggest that proper constants be used. It should be allowed to combine flags. It should also be noted that the maximum number of flags in a system such is this is approximately 32 (give or take one depending on the storage mechanism).</p>

    <p>There should probably also be a mechanism to create groups and load flags from groups. Also to deny a specific flag to a user that might be granted in a group. Eg 3 columns per user perms, groups, denied. Groups being a mask of 32 possible groups (eg user, admin, etc). The combination of which could allow for a read-only admin with a debugging flag by adding (debug | (sumof(admingroup|usergroup)) &^ write</p>

    <p>Also, the storage mechanism eg a db should be offloaded from this class. Eg DBLoad should just be Load($whateverdataisneeded) leaving it to the user to define the db methods</p>

    <p>$0.02 </p>

    <p>Kevin</p>

  2. Jun 21, 2006

    <p>Not clear what exactly is supposed to be loaded and by what key. E.g. in DB case it may be logical to load permissions for given user, but it is not quite clear how these would work - what if the user has different permissions in different contexts? How do you tell what exactly to load?<br />
    Also if it not completely clear if the permission levels have to be bitmasks or can be combinations too, e.g.:<br />
    read = 1<br />
    modify = 2<br />
    create = 4<br />
    admin = 7</p>

    <p>and maximum 32 levels of permissions - if thery are represented as int - can be too little.</p>

  3. Jun 21, 2006

    <p>Constants are normally defined during creation of the class and are fixed across all uses of that class unless edited, By using an array the key names and values are controller by the developer.</p>

    <p>I do agree there should be some sort of group flags, the 32 value limit can be gotten around by having the option to use gmp functions.</p>

    <p>I agree, removing dbload, making ArrayLoad just load and maybe making it possible to define a call_back function this way loading of permissions doesn't happen until its "needed". This way pages that don't need to check permissions don't incur the overhead.</p>

    <p>The array loaded should be all possible bitmasks possible so any combination can be checked against.</p>

    <p>A way to "extend" the whole 32 levels issue would be to have seperate group and standard bitmask, this would allow 32 seperate masks + an unlimited number of combinations.</p>

    <p>Instead of defining admin = 8 you could define admin as a group of masks. Due to the complex nature though groups might need to be handled through a diffrent function set.. This would ensure no overhead for those that only wanted 32 masks but allow the flexibility to have groups only if needed.</p>

    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    if(permCheck('read') OR groupCheck('admin')) {
    do X
    }
    ]]></ac:plain-text-body></ac:macro>

  4. Jun 21, 2006

    <p>Ok most of the above comments have been addressed, would just like to comment on groups.</p>

    <p>Groups have been worked in and allow you to reference a "group" of masks using a single key.</p>

    <p>In reality, Instead of defining an "admin" key and wasting a bit you could assume anyone with Read, Write, Delete = Admin. The current code leaves that level of detail up to the developer.</p>

    <p>The group functions just make handling that easier <br />
    Instead of<br />
    permCheck('read') AND permCheck('write') AND permCheck('delete') to check for Admin it can just be</p>

    <p>groupCheck('Admin')</p>

    <p>If a page requires Mod or Edit you can do permCheck('Edit') OR groupCheck('Mod') if your permissions are setup right theres no need to do a permCheck('Admin').</p>

    <p>If you want you can also do something like groupCheck('Mod') AND !permCheck('Suspended') something like this would allow you to suspend a users permissions giving them limited access but not destorying there previous permission settings.</p>

    <p>So while without using gmp your still limited to 32 bit limits theres no need to waste space defining Admin, or Moderator, you can instead just create a group with all those permissions in there.</p>

    <p>Now an Admin with all permissions by default passes ANY perm or group check you do.</p>

    <p>In the end though limits and "denied" methods are in the hands of the developer not this class. Its the developers job to ensure a normal user shouldn't have X permissions.</p>

    1. Jun 22, 2006

      <p>I don't think relying on gmp functions is good - and limit of 32 permissions would be exhausted quite quickly, think about every site part - like news, catalog, etc. - having at least 2 access levels - read & write, so once you have more than 16 different parts on your site, you're out of luck. </p>

      <p>What is still unclear for me is the database link - what exactly is supposed to be stored in the DB and what should be loaded?</p>

      1. Jun 22, 2006

        <p>It doesn't rely on gmp, using gmp is just an extra that is only used if its available and wanted.</p>

        <p>As to the 16 page limit thats only if your micromanaging permissions in which case in reality you might need something more robust.</p>

        <p>The only way around the 32 bit limit is with gmp or to do multi column permission checks like</p>

        <p>$array<ac:link><ri:page ri:content-title="'read'" /></ac:link><ac:link><ri:page ri:content-title="bita" /></ac:link> = 1<br />
        $array<ac:link><ri:page ri:content-title="'read'" /></ac:link><ac:link><ri:page ri:content-title="bitb" /></ac:link> = 2</p>

        <p>then checking for read becomes if (user_bita & bita) AND (user_bitb & bitb)</p>

        <p>I can and have done this before, so if people feel a deeper level of base permissions are needed we can do that it just becomes harder to manage and requires 2 fields for the user storage.</p>

        <p>I stuck with the simple method to keep it lightweight, maybe a Zend_Perms and a Zend_Perms_64bit or something that way a person can choose there level of need?</p>

        <p>The database stuff has been removed, now theres just a Load function which you pass your array of keys and bits.</p>

  5. Jun 21, 2006

    <p>I think a better way might be:</p>

    <p>$permissions = Zend_Permissions();</p>

    <p>$permissions->define("read");<br />
    $permissions->define("write");<br />
    $permissions->define("delete");<br />
    $permissions->define("drink from carton");<br />
    $permissions->define("security council veto");</p>

    <p>$permissions->createGroup("administrator")<br />
    ->addPermission("read")<br />
    ->addPermission("write")<br />
    ->addPermission("delete");</p>

    <p>$permissions->createGroup("contributor")<br />
    ->addPermission("read")<br />
    ->addPermission("write");</p>

    <p>$permissions->createGroup("visitor")<br />
    ->addPermission("read");<br />
    ->addPermission("drink from carton");</p>

    <p>$permissions->createGroup("president")<br />
    ->addPermission("read")<br />
    ->addPermission("write")<br />
    ->addPermission("delete")<br />
    ->addPermission("security council veto");</p>

    <p>Of course, these could added as an array, or a list, or whatever.</p>

    <p>In the class, this would automatically have the effect of:</p>

    <p>read = 1<br />
    write = 2<br />
    delete = 4<br />
    drink from carton = 8<br />
    security council veto = 16</p>

    <p>administrator = 7<br />
    contributor = 3<br />
    visitor = 9<br />
    president = 23</p>

    <p>It would just be a matter of bitwise operations:</p>

    <p>public function addPermission($permission)<br />
    {<br />
    $this->flags = $this->flags | $permission;<br />
    return $this;<br />
    }</p>

    <p>public function removePermission($permission)<br />
    {<br />
    $this->flags = $this->flags & ~$permission;<br />
    return $this;<br />
    }</p>

    <p>public function hasPermission($permission)<br />
    {<br />
    return ($this->flags & $permission);<br />
    }</p>

    1. Jun 21, 2006

      <p>First you have now gone back to the same 32 field limit, you just have a nice pretty way to get there <ac:emoticon ac:name="wink" />.</p>

      <p>Second you can't and 2 combined values, if any one bit matches in each side it returns true.</p>

      <p>Example</p>

      <p>$user = 3 ( read + write );<br />
      $admin = 7 ( read + write + delete );</p>

      <p>$admin & $user = true when it should be false, the user only has read and write not delete.</p>

      <p>You have to check each flag by itself or it won't work. This is the reason I seperated the group functionality from the normal permissions</p>

      1. Jun 22, 2006

        <p>That's why groups are added separately... you would check group membership with a different function (isMemberOf).</p>

        1. Jun 22, 2006

          <p>Yea I have that in there, I just forgot to have a way to load the group array directly.. This is now adjusted.</p>

          <p>Thanks for the input, the group idea makes it easier to manage a large setup.</p>

          <p>Still looking into adding some simple permission/group management functions, Possible in a seperate class since they would only be needed when managing permissions not when actively using them in most cases.</p>

          1. Jun 22, 2006

            <p>I'm still not sure how to get around the signed integer limit without GMP and have it still be reliable. I wonder if anyone else has any ideas..?</p>

            1. Jun 22, 2006

              <p>The only way I know of and I have done it before is to use 2 bitmasks per key but then you REALLY need a good management class to handle creating and editing masks or it becomes a big pain</p>

              <p>$perms<ac:link><ri:page ri:content-title="'Read'" /></ac:link><ac:link><ri:page ri:content-title="'maska'" /></ac:link> = 1<br />
              $perms<ac:link><ri:page ri:content-title="'Read'" /></ac:link><ac:link><ri:page ri:content-title="'maskb'" /></ac:link> = 1<br />
              $perms<ac:link><ri:page ri:content-title="'Write'" /></ac:link><ac:link><ri:page ri:content-title="'maska'" /></ac:link> = 2<br />
              $perms<ac:link><ri:page ri:content-title="'Write'" /></ac:link><ac:link><ri:page ri:content-title="'maskb'" /></ac:link> = 1<br />
              $perms<ac:link><ri:page ri:content-title="'Delete'" /></ac:link><ac:link><ri:page ri:content-title="'maska'" /></ac:link> = 4<br />
              $perms<ac:link><ri:page ri:content-title="'Delete'" /></ac:link><ac:link><ri:page ri:content-title="'maskb'" /></ac:link> = 1<br />
              $perms<ac:link><ri:page ri:content-title="'Admin'" /></ac:link><ac:link><ri:page ri:content-title="'maska'" /></ac:link> = 128<br />
              $perms<ac:link><ri:page ri:content-title="'Admin'" /></ac:link><ac:link><ri:page ri:content-title="'maskb'" /></ac:link> = 128</p>

              <p>$userperms = "128|128"</p>

              <p>function maskcheck($key) {<br />
              $umask = explode("|", $userperms);<br />
              if(($umask<ac:link><ri:page ri:content-title="0" /></ac:link> & $perms<ac:link /><ac:link><ri:page ri:content-title="'maska'" /></ac:link>) AND ($umask<ac:link><ri:page ri:content-title="1" /></ac:link> & perms<ac:link /><ac:link><ri:page ri:content-title="'maskb'" /></ac:link>))

              Unknown macro: {</p> <p> }

              <br />
              }</p>

              1. Jun 22, 2006

                <p>LOL, I really have no idea what you wrote there thanks to Confluence. <ac:emoticon ac:name="smile" /></p>

                1. Jun 22, 2006

                  <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
                  $perms['Read']['maska'] = 1
                  $perms['Read']['maskb'] = 1

                  $userperms = '1|1';

                  function maskcheck($key) {
                  $umask = explode("|", $userperms);
                  if(($umask[0] & $perms[$key]['maska']) AND ($umask[1] & $perms[$key]['maskb']))

                  Unknown macro: { echo "Passed" }

                  }
                  ]]></ac:plain-text-body></ac:macro>

  6. Jun 22, 2006

    <p>Not meaning to throw a ranch in there but would not a solution like LiveUser be more appropriate. It should be possible to implement such a bitwise mechanism.</p>

    <p>It does not currently run under E_STRICT but an effort could be made to have PHP5 E_STRICT compliant code.</p>

    <p>It does seem to me like reinventing the wheel when options exist.</p>

    <p>Disclaimer: I am one of the developers of LiveUser.</p>

    1. Jun 22, 2006

      <p>LiveUser is more a Auth system, this is a lightweight permissions system only, it isn't meant to handle auth or replace something like LiveUser.</p>

      <p>This is something that would be used in conjuction of an Auth system, or say in conjunction with http_auth</p>

  7. Jun 22, 2006

    <p>My concerns at this point are two things:</p>

    <p>1. The lockdown of permissions to one specific context by making the class static. The developer has charge of what the context of the permission-set is, but there can be only one. What if the developer has both an "area"-set and a "page"-set or something completely different, or loading different users permissions at the same time? You might have taken this into consideration, my apologies then, but i still don't think a static ACL is the way to go here.</p>

    <p>2. I don't think we need to specify what kind of permission sources are available (user permissions and group permissions), when it can be made generic. In the example below you could maybe name the load-methods, so that they can be implicitly accessed from the permission method. $ob->load(12, 'user') $ob->permission('read', 'user')</p>

    <p>I have not given the actual class much thought, but i have a hard time seeing that this could impose any serious overhead.</p>

    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    // Create bitmap
    $zone_acl = new Zend_Acl(array('read' => 1, 'write' => 2, 'delete' => 4, 'suspended' => 8));

    // Load group permissions
    //
    // Of course this could also be set by passing an integer value
    $zone_acl->load(array('read', 'write'));

    // Load user permissions
    //
    // Priority is set by first come first serve, flip the direction?
    // The second parameter allows us to deny certain permissions even if they are given
    // by a previous load
    $zone_acl->load(array('delete'), array('read'));

    // This should return false because we added
    if($zone_acl->permission('read') && !$zone_acl->permission('suspended'))
    {
    echo 'true';
    }
    else
    {
    echo 'false';
    }
    ]]></ac:plain-text-body></ac:macro>

    <p>Any thoughts?</p>

    1. Jun 22, 2006

      <p>It was made static purely for ease of access, since its very likely permissions will be needed everywhere including views, I have no problem with it not being static it just means a lot of registery fun.</p>

      <p>As you mentioned by removing the static requirements you no longer really need seperate group functionality as you can do things like</p>

      <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
      $perms = new Zend_Perms($permsarray);
      $groups = new Zend_Perms($grouparray);

      if($groups->checkPerms('admin') OR $perms->checkPerms('write')) {

      }
      ]]></ac:plain-text-body></ac:macro>

      <p>I would almost prefer the ability to maybe have "userspace" within the static functions though so ease of use is kepted</p>

      <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
      Zend_Perms::permCheck('Admin','GroupCheck');
      Zend_Perms::permCheck('Read','PermCheck');
      Zend_PErms::permCheck('FeedbackPage','PageCheck');
      ]]></ac:plain-text-body></ac:macro>

      <p>This would give the same flexability your mentioning, while keeping the ability to easily access.</p>

  8. Aug 04, 2006

    <ac:macro ac:name="note"><ac:parameter ac:name="title">Zend Comments</ac:parameter><ac:rich-text-body>

    <h3>Summary</h3>

    <p>It is clear that the purpose of the Zend_Perms proposal is to provide a simple interface for managing and checking against sets of access permissions. Indeed, the proposed class skeletons supply such a simple interface, and the proposal makes reference to an implementation based on bit fields, available either as PHP integers or as GMP resources that facilitate arbitrary field sizes. The proposal leaves many details up to speculation, as evidenced by comments received up to now.</p>

    <p>The features provided by this proposal may be categorized as <strong>authorization</strong>. Authorization may be described as the process of answering a simple question, to which a boolean answer is expected: in general OOP terms, whether a requesting object is allowed access to another object.</p>

    <p>A typical example is that of a browser requesting a web resource, such as <a class="external-link" href="http://www.example.com/admin">http://www.example.com/admin</a>, which is intended to be a secured, administrative area of a website. The underlying web application would thus need to at least distinguish between authenticated website administrators and unauthenticated, "guest" visits. <strong>Authentication</strong>, determining whether an object is what it purports to be, can be considered distinct from, however related to, authorization, which this proposal addresses. For the framework we should like to have only loose coupling between authentication and authorization, so as to support flexibility and extensibility for meeting PHP developers' various needs.</p>

    <p>The development team from Zend unequivocally supports having an authorization component in the framework, and I personally will be making efforts to facilitate such development. It is the general consensus from Zend at this time, however, that the Zend_Perms proposal be formally rejected, in favor of a more robust design that solves the authorization problem in the 80/20 spirit, from the smallest client projects to more full-featured enterprise applications.</p>

    <p>Despite the proposal rejection, the concepts here remain must-have for the framework. It is my personal hope that we use what is learned here to help design the Zend Framework authorization component. We have another proposal named Zend_Acl that is a slightly different approach toward meeting similar goals. I would like to direct future attention with respect to working on the authorization component for the framework here:</p>

    <p><a class="external-link" href="http://framework.zend.com/wiki/x/Hwo">http://framework.zend.com/wiki/x/Hwo</a></p>

    <p>Through continued discussions and proposal development we should soon be able to arrive to a best-of-breed API and begin adding code for a framework authorization component. Probably a reasonable goal would be to arrive on a revised proposal within a week or two, thereafter adding code to either the laboratory or the incubator for continued development toward a core release.</p>

    <h3>Notes</h3>

    <p>Bit field implementations can perform optimally in terms of time and storage requirements for operations. The tradeoff is that we either limit the number of access privileges to the size in bits of a PHP integer (e.g., 32) or we depend on the availability of GMP functions. The API should not require an implementation using bit fields. In any case, we should focus more on the use of the component through its proposed API than on backend storage and other implementation details. It is important that the API be simple and robust, despite the possibility of complex or varied implementations.</p>

    <p>We lean more toward naming an authorization component "Zend_Acl." Though the final design may not perfectly be defined as an Access Control List approach (maybe it is a Role Based Access Control approach, instead), the term "ACL" is shorter than "Authorization," less ambiguous than "Auth", and should be easily recognized by the community as facilitating access control or authorization.</p>

    <p>The API should allow for having a Db backend, including Db adapter specific implementations (e.g. see <a class="external-link" href="http://dev.mysql.com/doc/refman/5.0/en/set.html">http://dev.mysql.com/doc/refman/5.0/en/set.html</a>).</p>

    <p>A fully functioning authorization control system will likely depend on or use either sessions or authentication mechanisms.</p>

    <p>In general, when a static is absolutely needed, it should be protected, not private.</p>

    <p>Consider the ability to serialize instances of authorization component objects, placing those serializations in a Zend_Config configuration.</p>

    <p>Generally, access controls are more easily managed by allowing for groupings of request objects that are intended to be perform similar functions. This concept is also known as "roles." For example, both Susie and Joe are administrators for a website. Rather than directly assigning access controls to each person, permissions can simply be assigned once to the role of an "Administrator," having both Susie and Joe as members.</p>
    </ac:rich-text-body></ac:macro>

  9. Aug 07, 2006

    <p>Just a quick unofficial comment from me .. I do see value in this proposal for those who need an extremely lightweight solution and only the functionality offered by this component. For various reasons, we generally do not support multiple, simultaneous solutions for the same problem in the ZF core components. However, I do hope to see this component implemented and added to the Laboratory, and thus made available for those who seek this type of lightweight solution.</p>

    1. Aug 07, 2006

      <p>I agree, and will continue working on this as I use it for my own projects anyway.</p>

      <p>However, there are a couple good points brought across that I am going to change.</p>

      <p>1. The current setup requires you already fully understand bitfields and can build your own array and that you have to track what bit values are used. I am going to get rid of that requirement and add a createbit function IE </p>
      <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
      $perms->createbit('Admin')
      ]]></ac:plain-text-body></ac:macro>
      <p>This way the person using the class doesn't have to have any knowledge of the bit values just the proper keys.</p>

      <p>2. The bit functions are going to be put into interfaces, with the plan to have 3 bitfield interfaces, 32bit, 64bit, gmp<br />
      32bit = Uses standard bitmath<br />
      64bit = Uses 2 pair for each flag "faking" a 64bit limit<br />
      gmp = Only limited by the gmp function</p>

      <p>3. I will add some groupings, however there use is not required, instead they build ontop of the normal bitflag operations. This way they will add no overhead other then a few lines of code thats not used unless your calling the group functions.</p>

      1. Aug 07, 2006

        <p>Just a side note on the "createbit" portion, Used this way creates some complications for storage. If you for exampe do the following</p>
        <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
        $perms->createbit('Admin');
        $perms->createbit('Member');
        $perms->createbit('Anonymous');
        ]]></ac:plain-text-body></ac:macro>
        <p>Then decide later on to add a value</p>
        <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
        $perms->createbit('Superuser');
        $perms->createbit('Admin');
        $perms->createbit('Member');
        $perms->createbit('Anonymous');
        ]]></ac:plain-text-body></ac:macro>
        <p>All your bits are shifted, if the true bit value was stored say in a users settings it would no longer be valid, in fact such mistakes could easily create issues.</p>

        <p>I think if the "easy" methods of access are used, access to the "true" bit values should be restricted to prevent users from shooting themselves in the foot.</p>

        <p>Matter fact this "group" interface may need to be its own class for security sake.</p>

  10. Sep 17, 2006

    <p>Is there a reason you chose a static interface, as opposed to passing a $bitfield object in the registry?</p>

    <p>Why do you make people choose 32-bit, 64-bit, or GMP? I don't think that's needed or desirable. If GMP is installed, use GMP. Otherwise, if, in a particular bitfield, they exceed 32 bits, it should automatically switch over to 64-bit processing.</p>

    <p>I still think an ideal bitfield interface would be something like my previous post:</p>

    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    $bitfield = Zend_Bitfield();
    $bitfield->createBit('read');
    $bitfield->createBit('write');
    $bitfield->createBit('delete');

    $bitfield->createGroup('administrator')
    ->addBit('read')
    ->addBit('write')
    ->addBit('delete');
    $bitfield->createGroup('contributor')
    ->addBit('read')
    ->addBit('write');
    $bitfield->createGroup('visitor')
    ->addBit('read');

    Zend::register('bitfield', $bitfield);

    //--------------------------------------------------------------

    $bitfield = Zend::registry('bitfield');
    if (!$bitfield->hasBit($usergroup, array('read', 'write', 'delete'))) {
    print 'Administrators will never see this';
    }
    ]]></ac:plain-text-body></ac:macro>

    <p>Well, that's just my outlook.</p>

    <p>By the way, your class index is a bit messed up.</p>

    1. Sep 17, 2006

      <p>Static to make it easy access, but thats up for discussion and easily changable.. If its not static theres really no need for the "group/namespace" support, since you could just create a new object.</p>

      <p>Choice because some people need options, Maybe they don't need the overhead of GMP because there only using a couple bits, Or maybe they know they won't have access to GMP so they can use the 64-bit setup. I have no objection to changing the defaults around, maybe have an "auto" mode that will use gmp if its available but the choice needs to be there.</p>

      <p>Auto switching is not easy due to the way you have to store the 64 bit values, the only easy way to handle the compares is to always use the same comparision.</p>

      <p>Also if what if someone needs to do a 32 + 64 bit, You have to translate the 32 bit to 64 bit to do the comparision so you might as well have stored everything 64 bit to begin with.</p>

      <p>Maybe Zend_Bitfield_ACL could be done in the future but this has moved away from being an ACL/Permissions, its purely a bit field manager to provide an easy to use method to handling bit values, If someone wants to extend it to provide the functionality you suggest that is great.</p>

      1. Sep 20, 2006

        <blockquote>
        <p>If its not static theres really no need for the "group/namespace" support, since you could just create a new object.</p></blockquote>

        <p>True. I thought about that, but I was still in ACL mode. If ACL is a separate class (or eventually built on top of this), then groups are unnecessary and the class is simplified quite a bit.</p>

        <blockquote>
        <p>Choice because some people need options, Maybe they don't need the overhead of GMP because there only using a couple bits, Or maybe they know they won't have access to GMP so they can use the 64-bit setup. I have no objection to changing the defaults around, maybe have an "auto" mode that will use gmp if its available but the choice needs to be there.</p>

        <p>Auto switching is not easy due to the way you have to store the 64 bit values, the only easy way to handle the compares is to always use the same comparision.</p>

        <p>Also if what if someone needs to do a 32 + 64 bit, You have to translate the 32 bit to 64 bit to do the comparision so you might as well have stored everything 64 bit to begin with.</p></blockquote>
        <p>Okay, how about this: default is 32-bit (Zend_Bitfield::BIT32). That's set in an internal value. Once it exceeds 32 bits, it calls a function that determines if GMP is installed. If so, it uses GMP; otherwise, it uses the custom 64-bit mode. That function also calls a conversion function that changes 32-bit values to 64-bit representations.</p>

        <p>The user can also manually set the "bit mode" in the constructor if he knows he'll be using one or the other.</p>

        <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
        $bitfield = new Zend_Bitfield(Zend_Bitfield::BIT64);
        ]]></ac:plain-text-body></ac:macro>
        <p>or</p>
        <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
        $bitfield = new Zend_Bitfield(Zend_Bitfield::GMP);
        ]]></ac:plain-text-body></ac:macro>

        1. Sep 20, 2006

          <p>Thats all reasonable, A converter would be usefull anyways just for management.</p>

          <p>The only issue there would be storage, The returned storage values for 64bit are diffrent then 32bit.</p>