Master-X
Форум | Новости | Статьи
Главная » Форум » Программинг, Скрипты, Софт, Сервисы » 
Тема: ООП в ПХП
цитата
07/03/14 в 16:56
 Lexikon
Yacc писал:
Это 5к строк?

Нет smail101.gif
это я как пример поинтересовался
сейчас уже потихоньку начал втыкать в эти все тонкости.
При мер был как момент понять как и куда.
цитата
07/03/14 в 17:03
 Yacc
В конкретно данном примере класс не нужен вообще, он тут тебе вообще ничего не решает.

Надо мыслить "П" в ООП как "проектирование". В этом смысле ООП начинается задолго до написания первой строчки кода.
цитата
07/03/14 в 17:13
 Lexikon
grozny писал:
$this обязательно надо
а пхп сила именно потому что можно ничего не объявлять icon_smile.gif
только если в конфиге пхп у тебя на хостинге будет error_reporting E_ALL стоять, то он будет ругаться на такое. но работать все равно будет)


Это для локалки код пишется.

Вот тут всплыла еще такая проблема при работе цыкла

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 500001 bytes)

установлен WAMP

хотелось бы разобраться, это можно как то решить не прибегая к увеличении памяти? Может какие то переменные должны очищаться, после каждого круга, это вообще возможно?
цитата
07/03/14 в 17:20
 idk2045
Lexikon писал:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 500001 bytes)

установлен WAMP

хотелось бы разобраться, это можно как то решить не прибегая к увеличении памяти? Может какие то переменные должны очищаться, после каждого круга, это вообще возможно?

что за цикл-то? 130 метров это дофига.
цитата
07/03/14 в 17:20
 Lexikon
Yacc писал:
В конкретно данном примере класс не нужен вообще, он тут тебе вообще ничего не решает.

Надо мыслить "П" в ООП как "проектирование". В этом смысле ООП начинается задолго до написания первой строчки кода.


Возможно.
У меня массив на 25 значений, цыклом нужно пройти 20к строк, по этим значениям нужно сформировать текст он зависит от определенных параметров которые указаны в значениях массива.
цитата
07/03/14 в 17:23
 Lexikon
grozny писал:
что за цикл-то? 130 метров это дофига.

состоит 25к повторов, каждый цыкл возвращает массив на 25 значений, каждое значение, это строка в среднем на 50 символов
цитата
07/03/14 в 17:31
 idk2045
Lexikon писал:
нужно сформировать текст

Lexikon писал:
цыклом нужно пройти 20к строк

когда проходишь большой файл, или делаешь большую выборку из базы, то обычно все не хранишь в памяти, а по одной строке отрабатываешь и сразу записываешь куда надо. ну если есть такая возможность по алгоритму.
цитата
07/03/14 в 17:32
 Lexikon
grozny писал:
когда проходишь большой файл, или делаешь большую выборку из базы, то обычно все не хранишь в памяти, а по одной строке отрабатываешь и сразу записываешь куда надо. ну если есть такая возможность по алгоритму.

сразу не глянул, тут похоже проблема в классе Snoopy.class
Это старонний, не мой, просто подключаю его, чтоб он имитировал обращение браузера. Без него ни как. По крайней мере я незнаю как это сделать проще. Если без него то выдает что у меня нет возможности сохранять кукисы и все. Нужно как то в заголовках это всё передавать, чтоб обойти это. Я пробовал это сделать, но нет.
цитата
07/03/14 в 19:10
 Lexikon
всё, всплыла проблема
было так
919704
1120432
1341712

стало так
695768
665536
654416

Это кол-во памяти после каждого цикла
забыл закоментить массив в цикле в который доавлялись новые массивы, чтоб получить один многомерный.
цитата
09/03/14 в 20:48
 Lexikon
начал изучать ООП.
Поставил для себя задачу сделать дерево каталогов и вложить в них файлы, по идеи должно было получиться так

./dirData/_general/images/
./dirData/_general/pages/
./dirData/_general/fileNameList.dat

./dirData/09.03.2014/images/
./dirData/09.03.2014/pages/
./dirData/09.03.2014/fileNameListNew.dat

написал для этого такой класс class.DirStructure.php


<?php

/*
Класс для создания заданной структуры директорий
*/

class dirStructure
{
   // Переменные с именами директорий
   public $dirData          = "dirData";
   public $dirImages          = "images";
   public $dirPages          = "pages";
   public $dirGeneral         = "_general";

   // Переменные с именами файлов
   public $fileNameList       = "fileNameList.dat";
   public $fileNameListNew      = "fileNameListNew.dat";


   function createDir(){
        // Получаем текущую дату   
        $dateToday = date("m.d.Y");

      // Пути к основным директориям и файлам
      $toDirGeneral = $this -> dirData."/".$this -> dirGeneral."/";
      $toMainDirImages = $this -> toDirGeneral."/".$this -> dirImages."/";
      $toMainDirPages = $this -> toDirGeneral."/".$this -> dirPages."/";
      $toFileNameList = $this -> toDirGeneral."/".$this -> FileNameList;

      // Пути к новым директориям и файлам
      $toDirDate = $this -> dirData."/".$this -> dateToday."/";
      $toNewDirImages = $this -> toDirDate."/".$this -> dirImages."/";
      $toNewDirPages = $this -> toDirDate."/".$this -> dirPages."/";
      $toFileNameListNew = $this -> toDirDate."/".$this -> FileNameListNew;

      if (!is_dir($this -> dirData)){
         mkdir($this -> dirData);
               echo "Директория <b><i>".$this -> dirData."</i></b> СОЗДАНА! Путь к директории : (<b>".$this -> dirData."</b>). <br />";
        }


        if (!is_dir($this -> toDirGeneral)){
         mkdir($this -> toDirGeneral);
               echo "Директория <b><i>".$this -> dirGeneral."</i></b> СОЗДАНА! Путь к директории : (<b>".$this -> toDirGeneral."</b>). <br />";
        }
        if (!is_dir($this -> toMainDirImages)){
         mkdir($this -> toMainDirImages);
               echo "Основная директория <b><i>".$this -> dirImages."</i></b> СОЗДАНА! Путь к директории : (<b>".$this -> toMainDirImages."</b>). <br />";           
        }
        if (!is_dir($this -> toMainDirPages)){
         mkdir($this -> toMainDirPages);
               echo "Основная директория <b><i>".$this -> dirPages."</i></b> СОЗДАНА! Путь к директории : (<b>".$this -> toMainDirPages."</b>). <br />"; 
      }

          
   }
}




?>

Но вот ничего, кроме как создалась только первая директория /dirData/ и вылезли ошибки "Notice: Undefined property: dirStructure::$toDirGeneral in"

это файл script.php


<?php

header("Content-Type: text/html; charset=UTF-8");

include ("./class.DirStructure.php");

$object = new dirStructure;

$object -> createDir();

?>


Получется что те пути которые я формирую из переменных, вообще не так должны создаваться.
Подскажите люди добрые, что не так.
Спасибо!
цитата
09/03/14 в 21:06
 Stek
Для начала классы не должны ничего выдавать типа echo .

Далее $this->toDirGeneral у тебя не определено, отсюда и ошибка.

Ты определил $toDirGeneral как внутреннюю переменную в функции. А обращаешься к переменной класса $this->toDirGeneral.
цитата
09/03/14 в 21:45
 Lexikon
вон оно что.
Сейчас стал менять и пошло.
Понял ошибку, я почемуто думал что нужно всегда обращаться через $this ->, даже внутри функции.
Спасибо!
Но вот с echo, а как тогда быть если сообщить, что возникла та или иная проблема, к примеру в классе функция проверки наличия файлов. Как тогда выдать инфу что файлы не создалиь?
цитата
09/03/14 в 22:10
 Sterx
исключения или писать в какой нибудь
$this->error
цитата
09/03/14 в 23:49
 Stek
Если ошибки отлавливаешь сам, то верни false при неудаче или true при успехе . По началу так легче. Позже можно обрастать экзепшенами и прочими вещами. Но на начальном этапе это лишнее.
цитата
10/03/14 в 18:13
 Yacc
Lexikon писал:
написал для этого такой класс class.DirStructure.php

Зачем тебе для решения этой задачи класс, экземпляр которого еще и создавать надо? Во-вторых с таким решением смысла писать какой-то там класс вообще нет. Это равносильно тому, что ты прямо в индексе писал бы mkdir, mkdir, ... Завтра поменяется структура директории и ты что будешь делать? Новый класс писать? smail101.gif

Правильное решение выглядит так примерно:
Код:
<?php

class foo {
    static function bar ($files, & $root = []) {
        foreach ($files as $name => $value) {
            if (is_array($value)) {
                $root[] = $name;
                if ( ! is_dir($dir = implode(DIRECTORY_SEPARATOR, $root))) {
                    mkdir($dir);
                }
                self::bar ($value, $root);
            }
            else {
                file_put_contents(implode(DIRECTORY_SEPARATOR, $root) . DIRECTORY_SEPARATOR . $value, '');
            }
        }
        array_pop($root);
    }
}

$files   = [
    'dir1' => [
        'file1',
        'file2',
        'dir2' => [
            'dir3' => [
                'file3',
                'file4'
            ],
            'dir4' => []
        ],
        'file5'
    ],
    'file6'
];
$root = [realpath(dirname(__FILE__))];

foo::bar ($files, $root);
цитата
10/03/14 в 18:28
 Stek
Из "недочетов":
1. имя класса с маленькой буквы, должно быть с большой
2. функция в классе без указания public
3. в создании директории нет проверки на результат
4. в создании файла тоже как и в пункте 4

Совершенно не понял смысл с array_pop($root);

Ну и на довесок, вместо DIRECTORY_SEPARATOR можно везде смело использовать "/" , на виндах работает так же без проблем, как и на линксе.

А вообще молодец, что не поленился smail54.gif
цитата
10/03/14 в 21:30
 Yacc
Я-то писал чтобы Лексикон лес за деревьями увидел. Ты вон даже смысла array_pop($root) не понял, поди теперь вот в этом разберись:

Код:
<?php

class Foo {
    protected static $_errors;
    static function baz ($root, $files) {
        self::$_errors = [];
        set_error_handler(function ($no, $str, $file, $line, array $context) {
            if (0 === error_reporting()) {
                return false;
            }
            throw new ErrorException($str);
        });
        try {
            if ( ! is_dir($root) and false === mkdir($root, 0777, true)) {
                throw new ErrorException($root);
            }
            $root = [$root];
            self::bar($root, $files);
        }
        catch (ErrorException $ex) {
            return self::$_errors[] = $ex->getMessage();
        }
        restore_error_handler();
        return self::$_errors;
    }
    protected static function bar ( & $root, $files) {
        foreach ($files as $name => $value) {
            if (is_array($value)) {
                $root[] = $name;
                if ( ! is_dir($dir = implode(DIRECTORY_SEPARATOR, $root))) {
                    if (false === mkdir($dir)) {
                        array_pop($root);
                        throw new ErrorException($name);
                    }
                }
                self::bar ($root, $value);
            }
            else if (false === file_put_contents(implode(DIRECTORY_SEPARATOR, $root) . DIRECTORY_SEPARATOR . $value, '')) {
                throw new ErrorException($value);
            }
        }
        array_pop($root);
    }
}

$files   = [
    'dir1' => [
        'file1',
        'file2',
        'dir2' => [
            'dir3' => [
                'file18',
                'file4'
            ],
            'dir4' => []
        ],
        'file5'
    ],
    'file6',
    'dir5' => [
        'file7'
    ]
];
$root = realpath(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'dir0';

if (count($errors = Foo::baz ($root, $files)) > 0) {
    printf('<pre>%s</pre>', print_r($errors, 1));
}


Имена файлов имеет смысл отфильтровать еще, но это если неизвестно кто и как будет их формировать. А если для себя, то это уже неваляшка. icon_smile.gif
цитата
11/03/14 в 02:24
 Stek
Вот это треш с эзкепшенами ты наворотил. Я бы по началу упростил все, выкинув экзепшены, переопределение ошибок и разделив логику создания файлов и директорий, с их проверками.

<?php
error_reporting(E_ALL);

class Foo {
    /***
     * Элементарная рекурсия в 7 строк.
     * @param $path
     * @param $config
     * @return bool
     */
    public static function make_tree($path, $config) {
        /*
         * просто читаем конфиг.
         * Если элемент массив - значит это директория. Создаем и передаем ее конфиг на себя
         * Если элемент ключ - значит просто файл
         * */
        foreach ($config as $node_key => $node_value) {
            if (is_array($node_value)) {
                self::create_dir($path.'/'.$node_key);
                self::make_tree($path.'/'.$node_key, $node_value);
            } else {
                self::create_file($path.'/'.$node_value);
            }
        }
        return true;
    }

    /***
     * Создаем директорию, если доступна запись и такой директории нет.
     * По желанию можно удалять существующую, переименовывать и прочее.
     * Дополнительные проверки и т.п. Суть в том, создание отделено от логики.
     * @param $path string
     * @return bool
     */
    public static function create_dir($path) {
        if (!file_exists($path) && is_writable(dirname($path))) {
            mkdir($path, 0777, true);
            return true;
        } else {
            return false;
        }
    }

    /***
     * Та же фигня что и выше
     * @param $path
     * @param string $content
     * @return bool
     */
    public static function create_file($path, $content = '') {
        if (!file_exists($path) && is_writable(dirname($path))) {
            file_put_contents($path, $content);
            return true;
        } else {
            return false;
        }
    }
}

$files   = [
    'dir1' => [
        'file1',
        'file2',
        'dir2' => [
            'dir3' => [
                'file18',
                'file4'
            ],
            'dir4' => []
        ],
        'file5'
    ],
    'file6',
    'dir5' => [
        'file7'
    ]
];

$root = realpath(dirname(__FILE__)).'/dir0';

// создаем нужную директорию если необходимо
Foo::create_dir($root);

// а тут создаем по конфигу
Foo::make_tree($root, $files);


Вообще по хорошему, стоило бы выделить файловые операции в отдельный класс. Тогда их потом можно из других классов использовать , зная что там уже есть все необходимые проверки и прочее.
цитата
11/03/14 в 06:33
 Lexikon
Сразу хочется сказать Вам обоим спасибо за представленные коды. smail54.gif

Yacc писал:
Зачем тебе для решения этой задачи класс, экземпляр которого еще и создавать надо? Во-вторых с таким решением смысла писать какой-то там класс вообще нет. Это равносильно тому, что ты прямо в индексе писал бы mkdir, mkdir, ... Завтра поменяется структура директории и ты что будешь делать? Новый класс писать?


Создание директорий через класс, это как вариант начала познания ООП. То что пишется в книгах и показывается в видеоуроках, это все наглядно, нужно начать самому что то делать чтоб понять до конца как оно работает.

Вот еще интересны такие моменты как (:icon_smile.gif - это как я знаю "оператор разрешения области видимости". И далее если цитировать строки из книги - "Статические функции полезны для совершения действий, относящихся к самому классу, но не к конкретным экземплярам этого класса."
Я просто не до конца понимаю сути создания статического метода? Как в моем понимании так, статический метод нужен для использования его внутри только самого класса, при этом обратиться к нему можно только через :: и это создано только для того чтоб его не вызывали в объекте?

И касаемо:
if (count($errors = Foo::baz ($root, $files)) > 0) {
    printf('<pre>%s</pre>', print_r($errors, 1));
}
выше говорилось что в классах ненужно использовать всяческие операторы выводов, но тут все таки вывод через print_r() или в данном случае это есть исключание?
цитата
11/03/14 в 11:43
 Stek
Lexikon писал:
Я просто не до конца понимаю сути создания статического метода

Просто тупо требуется опыт и перелапачивание сотни вариантов, что бы научиться определять где и как удобнее.
Yacc сделал через статик, я повторил, что бы не сильно отличаться. Тут дело вкуса больше, ну или личного удобства.

Код:

class Foo{ public $id = 1; }

$a = Foo();
$b = Foo(); $b->id = 2;


Вот в примере выше класс у тебя уже полностью создал свой объект, и объектов может быть много и все они со своими значениями $id.

А со static уже не получится так.

Lexikon писал:
выше говорилось что в классах ненужно использовать всяческие операторы выводов, но тут все таки вывод через print_r() или в данном случае это есть исключание?

Это же вне класса сделано, просто как дебаг вывод окончательного результата. Т.е. к классу отношения не имеет.
цитата
11/03/14 в 11:56
 Yacc
Stek писал:
Вот это треш с эзкепшенами ты наворотил.

То что ты не в состоянии понять как это работает не значит что это трэш. Порядочные люди добавляют к таким сентенция imho.

Посмотрим на твой код. Неискушенному читателю вроде ТС-а может показаться, что он и вправду лучше чем мой: чистенький такой, прокомментировал все. Но взглянем правде в глаза.

Во-первых комменты. Блять как же меня бесят эти комменты, благо нетбинс их сворачивает сразу, а то бы меня кондрат бил по три раза на день. Вот скажи мне зачем методу в котором кроме mkdir нихуя нет комментарий длиннее чем сам метод? Я считаю, что если код нуждается в комментариях, то это плохой код. Особенно понравился коммент "Элементарная рекурсия на 7 строк". Это 5. smail101.gif

Во-вторых методы create_dir и create_file возвращают false в случае неудачи, но в методе create_tree этот результат не проверяется.

В третьих любое исключение или warning и даже notice в твоем коде приведет к остановке.

В четвертых клиент твоего класса в случае ошибки при создании файла или папки никогда не узнает что именно произошло, в лучшем случае он получит false.

Короче: поделка достойна абзаца в брошюре "Эта книга без затей, про ООП для детей". icon_smile.gif


Lexikon писал:
Я просто не до конца понимаю сути создания статического метода?

Статический метод это метод класса, то есть для вызова этого метода не нужно создавать объект этого класса.

Lexikon писал:
выше говорилось что в классах ненужно использовать всяческие операторы выводов

Выше много чего говорилось, не нужно принимать все за чистую монету. Заявление о том, что в классах нельзя использовать операторы вывода - бред сивой кобылы.

Вообще в кодинге нет такого слово "нельзя", все что позволяет сделать язык, можно и нужно использовать. Конечно при условии, что ты понимаешь что и зачем ты делаешь.
цитата
11/03/14 в 13:17
 Stek
Yacc писал:
Во-первых комменты.

Вообще то они для Lexikon написаны и их смысл показать, почему именно так я сделал.


Yacc писал:
Во-вторых методы create_dir и create_file возвращают false в случае неудачи, но в методе create_tree этот результат не проверяется.

Вот если бы ты почитал комменты, то эти бы вопросы у тебя не возникли.


Yacc писал:
В третьих любое исключение или warning и даже notice в твоем коде приведет к остановке.

Хреново, когда не читают комменты.

Yacc писал:
В четвертых клиент твоего класса в случае ошибки при создании файла или папки никогда не узнает что именно произошло, в лучшем случае он получит false.

Ахуенно хуево, когда не читают комменты smail101.gif

Yacc писал:
Короче: поделка достойна абзаца в брошюре "Эта книга без затей, про ООП для детей".

Только вот для того, что бы очистить уже существующею директорию или файл, мне достаточно изменить функцию их создания. А тебе придется лезть в свой цикл и там накручивать дополнительный код. Плюс код создания директории у тебя в двух точках дублируется.

У каждого свой стиль написания. Я к примеру стараюсь упрощать код, разделять его на логические части. Потом самому же будет легче расширять. И х.з. чего ты кипятишься smail101.gif
цитата
11/03/14 в 13:40
 Lexikon
Чем больше работаю с ПХП тем больше всего нового появляется icon_smile.gif
Это я еще без БД работаю, а там еще доп инфы появится. smail101.gif
А если вникать во всё, что связано то я х.з. сколько времени нужно на изучение.
Вот когда создают какие то серьезные движки, я думаю там не только нужно знать сам язык программирования, но и взаимодействия с сервером. Да и для серьезных проектов где нужна скорость там уже как я понял могут идти связки PHP с С++, для динамичности и интерактивности Ajsx, jQuery, JS хотя по сути эти первые два это по сути тот же JS. Ну и не останется в стороне БД icon_mrgreen.gif .
Вот тоже интересно, на чем пишут всяческие видеоплееры, те которые используют тьюбы? Java, ActionScript или что то другое.
Вот чититал, про гугл, так как я понял у них основное на чем пишут так это Python.
Всё это очень интересно, жалко времени мало!
цитата
11/03/14 в 13:46
 Lexikon
Stek писал:
У каждого свой стиль написания

Я два раза писал одно и то же, но с разными знаниями. Всё работает одинаково, но вот коды разные icon_smile.gif Учитывая прошлые косяки в следующий раз уже начинаешь писать по другому.
Это как почерк icon_smile.gif
цитата
11/03/14 в 15:21
 Stek
Lexikon писал:
Всё это очень интересно, жалко времени мало!

Поэтому нет смысла, пытаться узнать сразу все. Технологии даже в пхп меняются каждый год. Ухватить все не возможно, разве что только не целыми днями этим заниматься. Но тогда кто то должен тебе твое проживание оплачивать.

Lexikon писал:
Вот чититал, про гугл, так как я понял у них основное на чем пишут так это Python.

Гугл вроде свой GO разрабатывает, который ближе к процедурному, чем к OOP.

Lexikon писал:
Учитывая прошлые косяки в следующий раз уже начинаешь писать по другому.

Это аксиома, что программер одну и ту же задачу каждый раз будет решать по разному smail101.gif
Стр. « первая   <  1, 2, 3, 4  >  последняя »


Эта страница в полной версии