За последние 24 часа нас посетили 185484 программиста и 2137 роботов. Сейчас ищут 1853 программиста ...

Передача нескольких констант через побитовое сравнение

Тема в разделе "Прочие вопросы по PHP", создана пользователем TheShock, 20 июн 2009.

  1. TheShock

    TheShock Активный пользователь

    С нами с:
    30 май 2009
    Сообщения:
    1.255
    Симпатии:
    0
    Адрес:
    Київ
    PHP:
    1. <?
    2. var_dump(E_ALL); // int(6143)
    3. var_dump(E_ALL | E_NOTICE); // int(6143)
    4. var_dump(E_ALL ^ E_NOTICE); // int(6135)
    5. var_dump(E_ALL & E_NOTICE); // int( 8 )
    6. var_dump(E_ERROR | E_WARNING | E_PARSE); // int(7)
    7. var_dump(E_ERROR | E_WARNING | E_PARSE | E_NOTICE); // int(15)
    8. var_dump(E_ERROR | E_WARNING | E_PARSE | E_CORE_ERROR | E_CORE_WARNING); // int(55)
    Так вот - объясните, пожалуйста, кто знает, каким образом реализовано включение параметров в error_repporting и соединение нескольких в один и как это можно реализовывать в своих функциях. Желательно - на примере.
    Допустим, если взять обертку для строковых функций. В методе changeCase может быть первый параметр с тремя константами: Str::ALL, Str::FIRST, Str::TITLE и второй параметр с четырьмя константами: Str::DOWN, Str::UP, Str::DOWN_FORCED или Str::UP_FORCED. Например:

    Str::changeCase($string, Str::ALL, Str::DOWN_FORCED);

    Можно ли сделать передачу параметров туда так:

    Str::changeCase($string, Str::ALL | Str::DOWN | Str::FORCED);
    Str::changeCase($string, Str::TITLE | Str::UP);

    И если можно - то как? Желательно не воздушное описание: "Та там побитовое сравнение, че ж непонятного то?" - а детальное описание механизма действия этого ньюанса

    Интересует не данный определенный случай - интересует сама теория и жага знаний.
     
  2. Ну ты же знаешь как никсовые права комбинируются? Ну так и там точно так же -

    E_ERROR = 1 = 0001
    E_WARNING = 2 = 0010
    E_PARSE = 4 = 0100
    E_NOTICE = 8 = 1000

    Соответственно, их комбинации даются побитовым «или», то бишь, устанавливаются те биты, которые установлены хотя
    бы в одном операнде. - E_ERROR | E_PARSE = 5 = 0101, E_PARSE | E_NOTICE = 12 = 1100

    Примерно так. :)
     
  3. kostyl

    kostyl Guest

    Или можеш проверять на наличие в комбинации какого либо параметра с помощью побитного умножения "и":
    PHP:
    1.  
    2. <?php
    3. $sERROR_VALUE = 12;
    4. if (E_NOTICE & $sERROR_VALUE) {
    5.   echo 'E_NOTICE установлен';
    6. }
    7. if (E_ERROR & $sERROR_VALUE) {
    8.   echo 'E_ERROR  установлен';
    9. }
    10.  
    11. //Результат
    12. //E_NOTICE установлен
    13.  
    Тоесть получается:
    Код (Text):
    1.  
    2. $sERROR_VALUE = 1100;
    3. E_NOTICE      = 1000;
    4. result        = 1000  != 0 == TRUE  
    5. $sERROR_VALUE = 1100;
    6. E_ERROR       = 0001;
    7. result        = 0000  == 0 == FALSE  
    Фактически в $sERROR_VALUE установлены E_NOTICE | E_PARSE
     
  4. TheShock

    TheShock Активный пользователь

    С нами с:
    30 май 2009
    Сообщения:
    1.255
    Симпатии:
    0
    Адрес:
    Київ
    Точно, парни, спасибо. Вопрос еще такой.
    PHP:
    1. <?php
    2.     $dec = 55; // int(55)
    3.     $oct = 067; // int(55)
    4.     $hex = 0x37; // int(55)
    5.     // $bin = ???;
    6.     // Как указать в двоичном виде?: 110111
    7. ?>
    8.  
     
  5. Насколько я знаю, никак )
     
  6. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    мм а почему бы не использовать текстовые параметры и не мучиться с константами?
    my_function($str,"BLABLA_ON|FIFI_OFF")
     
  7. kostyl

    kostyl Guest

    Ну кто мучается, а кому очень удобно.
     
  8. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Принимай и парси строку вида 2x110010100011.
    Пример:

    PHP:
    1. <?
    2.  
    3. $bin = "2x110010100011"
    4.  
    5. $abc->SetOffset($bin);
    6.  
    7. ?>
    А переводить вручную (со сдвигом 4 бита).
     
  9. iliavlad

    iliavlad Активный пользователь

    С нами с:
    24 янв 2009
    Сообщения:
    1.689
    Симпатии:
    4
    А зачем? Всё равно в функцию значения передаются именами констант, а значения их можно и десятично задать.
     
  10. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    kostyl
    ещё хорошо бы узнать чем
     
  11. kostyl

    kostyl Guest

    Mr.M.I.T.
    ну, например, my_function не надо писать, примерно для таких значений:
    PHP:
    1.  
    2. <?php
    3. define('ET_MAXLENGTH', 1);
    4. define('ET_STRIMM', 2);
    5. define('ET_BASE64ENCODE', 4);
    6. define('ET_MUSTMATCH', 8);
    7. define('ET_INT', 16);
    8. define('ET_FLOAT', 32);
    9. ...
    10.  
     
  12. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    нипонял,
    и чё это даёт в удобстве установки параметров?
     
  13. kostyl

    kostyl Guest

    Потому что можно вветси ET_STRING = 14. Угадай какой набор констант она будет вмещать?
     
  14. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    неубедил,
    в моём варианте можно ввести тоже какой-нибудь общий параметр
    или если рассматривать вариант "пользовательских" хаков, тоже можно ввести константу какую-нибудь
    чёто типа


    define("E_ON_ALL","E_PAR1|E_PAR2");
    my_function($str,E_ON_ALL)

    Зы. И не *баться с кодами
     
  15. kostyl

    kostyl Guest

    Mr.M.I.T.
    Ладно, как говорят многие "каждому свое"...
    Зы.
     
  16. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Mr.M.I.T., а проверять как будешь, что передан параметр какой-либо? С интами всё просто

    PHP:
    1. <?php
    2. define('B1', 1);
    3. define('B2', 2);
    4.  
    5. function a($b) {
    6.     if ($b & B1) {
    7.         // ...
    8.     }
    9.  
    10.     if ($b & B2) {
    11.         // ...
    12.     }
    13. }
    ну и другие операции. например удалить из параметров B2
    PHP:
    1.  
    2. <?php
    3. $b &= ~B2;
     
  17. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    мм например
    PHP:
    1. if(in_array("B1",$opt)){
    2. }
    3. ....
    или если преобразовать опции в ключи
    PHP:
    1. if($opt['B1']){
    2. }
     
  18. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    вобщем буду работать с массивом опций
     
  19. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    В таком случае проще сразу массив передавать.
     
  20. TheShock

    TheShock Активный пользователь

    С нами с:
    30 май 2009
    Сообщения:
    1.255
    Симпатии:
    0
    Адрес:
    Київ
    Посчитал.. Для констант можно ставить след значения, закономерность видна невооруженным взглядом:
    Код (Text):
    1. Hex: 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000 и так далее
    2. Oct:  01,  02,  04, 010,  020,  040, 0100, 0200,  0400, 01000, 02000, 04000, 010000 и так далее
    Так каждая константа будет принимать свой уникальный вид и это, имхо, намного красивее и легче, чем в десятичной системе счисления. (Кто по памяти посчитает до 2^30 в десятичной системе?)
    Комбинируется, тоже очень красиво, потому можно использовать обе системы счисления, абы не десятичную, чтобы константы имели красивый и удобочитаемый стиль. Предлагаю использовать "Восьмеричную", кроме случаев когда реально удобней будет "Шестнадцатиричная". Отступы в классах предлагаю делать пробелами перед числом, после равно, чтобы крайняя правая цифра у всех констант была на одном уровне
    Код (Text):
    1.   // oct, восьмеричная
    2. FIRST  =   040;
    3. SECOND = 01000;
    4. BOTH   = 01040;
    5.   // hex, шестнадцатиричная
    6. FIRST  =  0x20;
    7. SECOND = 0x200;
    8. BOTH   = 0x220;
    9.   // dec, десятиричная
    10. FIRST  = 32;
    11. SECOND = 512;
    12. BOTH   = 544; // Так глянешь - и хз, что за число и что тут включено
    Спасибо всем высказавшимся.
     
  21. kostyl

    kostyl Guest

    TheShock
    Не сильно въехал... Один хер ты сравнивашь битовыми операндами. Или ты преобразования в строки имеешь в виду?
     
  22. TheShock

    TheShock Активный пользователь

    С нами с:
    30 май 2009
    Сообщения:
    1.255
    Симпатии:
    0
    Адрес:
    Київ
    kostyl
    те же побитовые операторы. просто хотел найти стиль, чтобы оно выглядело красиво и понятно.
     
  23. TheShock, ну, с одной стороны, удобно, а с другой - ты же не каждый день констаты считаешь, можно и десятичными задать, да и список обьвления констант можно из соседнего класса скопировать всегда. А так, да в восьмеричной особенно удобно.
     
  24. kostyl

    kostyl Guest

    TheShock
    Въехал ;)
     
  25. TheShock

    TheShock Активный пользователь

    С нами с:
    30 май 2009
    Сообщения:
    1.255
    Симпатии:
    0
    Адрес:
    Київ
    флоппик, не удобно в десятичной, потому что нельзя делать связанные константы. как в том же еррор-репортинге:
    Код (Text):
    1. E_ALL = E_ERROR | E_WARNING | E_PARSE | E_NOTICE | ... | E_USER_DEPRECATED
    2. E_ALL:
    3.     32767 in PHP 6
    4.     30719 in PHP 5.3.x
    5.     6143   in PHP 5.2.x
    6.     2047   previously
    Но я смотрю на эти числа и я, извините, в душе не ебу, что они значат и почему 32767 круче, чем 30719 и почему бы тогда не влепить туда 2000000, раз чем больше - тем лучше. Вот будет класс, а в нем будет какая-то константа: SOMETHING = 52473. А ты:
    1. Не можешь без мана понять, что она значит (какие константы включает)
    2. Не можешь добавить или удалить к ней чтото по умолчанию при рефакторинге без калькулятора.
    С хекс и окс системой это менее накладно.