Очень просто различает. Обмен данными происходит по сети. Клиент обращаясь на сервер занимает определенный порт(если не задан явно, ОС выделит один из свободных портов для клиента). Айпи клиента и порт который он занял когда соединялся с сервером и есть точка обратной связи сервера с клиентом. Но все это прозрачно для программиста, он работает лишь с дескриптором сокета своих клиентов.
Но этот класс нужен для улучшения производительности(скорость, более экономное потребление памяти на больших данных), а такими финтами вы скорее потеряете чем выйграете, если конечно вы не сохраняете этот объект где нибудь для использования его в последующих запросах без подобных финтов.
Адрес службы в данный момент не доступен для чтения WSDL. В ответ возвращается 403. А значит, сервис недоступен (выходит проблема на стороне сервера веб службы).
По умолчанию PHP кеширует WSDL, что бы каждый раз не лазить за одним и тем же документом, который как правило редко меняется на стороне сервера службы.
Скорее всего, когда вы обращались к удаленному сервису локально, сервис всё ещё был доступен.
Соответственно WSDL был закеширован, в связи с этим __getFunctions проанализировав структуру документа из кеша выдает вам результат, и ошибок не видно.
Попробуйте на локалке до создания клиента написать ini_set('soap.wsdl_cache_enabled', 0);
После запуска скрипта должно вывестись сообщение об ошибке, так как WSDL не будет прочитан из кеша, вместо этого PHP попытается загрузить документ по url службы и поймает 403 в ответ. (Добавление)
Или там тупо ограничение по айпи
есть одно НО - подключится может только 1 пользователь, хотя в socket_listen прописано 10.
Ну и что написано. Это вовсе не означает, что эта десятка будет обрабатываться вне очереди. Если количество соединений более чем 1, тогда эти соединения будут обрабатываться по очереди. В вашем случае после принятия соединения запускается бесконечный цикл который обрабатывает это соединение. Ввиду этого первое соединение не покидает очередь и остальные "ребята" не могут "работать". Если вы будете использовать блокирующие операции при обработки соединений, то никакие socket_select-ы тут не помогут, потому что обработка соединений происходит в одном потоке.
По мне нормально это когда:
Один писатель
Много читателей
Упал писатель? Специальный инстанс определяет нового писателя среди читателей
Проснувшийся писатель становится читателем
Как понимать "при каком вызове"? Что именно интересует?
Если количество вызовов - то завести статичную переменную в функции и инкрементить её при каждом вызове и передавать значение через объект который описывает исключение. Так же можно передавать и другие параметры. Как то так
т.е. реализовать класс class productList implements Iterator для этого дела?
В вашем случае проще всего использовать PDOStatement который и так Traversable с соответствующим типом fetch-а. Если создаете и заполняете экземпляр самостоятельно самый простой вариант это задействовать Generator
LIME
Приблизительно об этом я и говорил, о классе, экземпляры которого представляют определенный тип связанный с данными, которые подвергаются CRUD-у.
Может класс на предыдущей страничке был немного скудным, поэтому появились вопросы. Вот более ясный пример использования
$products=$storage->getList();//получили список объектов типа Product
//пример #2. insert и update
$product->setName($name);
$product->setPrice($price);
$storage->save($product);
Таким образом получаем унифицированный интерфейс обращения с продуктом и наличие соответствующего типа в коде а так же возможность локализировать некоторые стандартные вычисления(если они есть) в методах этого типа вместо того что бы дублировать их везде где используется product (Добавление)
Prizma пишет:
По реализации заполнения классов у меня появилось 2 варианта
Так у вас будет 2 цикла. Один заполнение массива, другой - для вывода данных из этого массива(через объекты которые в этом массиве). Тут явно напрашивается Traversable.
Есть другие способы более элегантные, по реализации.
Есть, но их объяснение может привести к нескольким простыням текста и столько же текста для того что бы ответить на ваши вопросы. Если бы вы их знали не задавали такие вопросы, по этому не нужно ля-ля...
Prizma пишет:
Код становится менее понятным и в случае нагруженности set, менее предсказуемым
Как уже говорил, в данном случае мы лишь помогаем PDO сделать свою работу. Такая реализация была предложена исходя из логики, что вы делаете проект, а изучать подробности "академической" реализации это долго. И это решение в 100 раз лучше чем то с чем вы пришли на форум создавая эту тему
Prizma пишет:
Сколько я в своей практике не использовал __set рано или поздно приходил, к тому, что эту часть кода приходилось переписывать, либо постоянно модифицировать.
А я вот не помню что бы мне приходилось это делать. Наверное не там применяли
Prizma пишет:
IDE не сможет тебе помогать
Вот LIME увидел реальную проблему, она есть и это не единственная проблема если докопаться с точки зрения ООП.
Об этом много писать. Не хочу, правда. Опять же, если не понятна суть примера, см ещё раз ответ на вторую цитату в этом посте...
однако магические методы точно использовать не хорошо..
Это кто сказал? Причины в студию, пруф, что это всегда зло. Нужно использовать, но с умом. А вообще выстрелить в ногу можно всякими инструментами, даже полезными, если разработчик плохо понимает с чем имеет дело.
Prizma пишет:
Этот код не полный там не хватает наверно execute... чтобы он работал
Конкретно в этом примере execute не нужен.
LIME пишет:
теди не слушай
Он ошибается
Я прекрасно понимаю причины твоих возражений касательно __set и отчасти ты прав, НО:
По поводу "Сетеры это лишнее знание для клиентского кода", в данном случае это очень удобно. Но да, остается возможность переопределить значение "прямым" обращением, инкапсуляция и все такое... Эту возможность можно "прикрыть" простой проверкой в __set.
Если исходить из логики, что __set предназначен для PDO, можно проверить, если свойство пустое, то пускать на запись, значит пишет PDO а не кто то в клиентском коде. Но если значение конкретному свойству уже присвоено, бросать исключение, значит это пытается сделать не PDO. Все просто. И простоту реализации сохранили, и такие знания у клиентского кода отняли.
LIME
Может мы по разному позиционируем этот вопрос. На мой взгляд это не модель, а то, что возвращает модель, то есть результат работы модели. Например, $productsModel->getList($offset, $limit), вернет какой то результат, если данные нашлись. А в какой форме она вернет результат, например в виде массива, объекта/набора объектов или что то ещё уже дело десятое и это решает разработчик в зависимости от того, что ему нужно и удобно. Конечный результат работы модели не является моделью, не является тем самым комбайном, который обращается в определенное хранилище за данными. Имхо... Как то так
LIME
А где ты здесь увидел модель? В данном случае экземпляр класса Product сущность, представляющая определенный тип в коде. У продукта есть название, цена и что то ещё. Этот продукт или набор продуктов в виде итератора/массива уже возвращает модель(возможно, какая нибудь ORM) как результирующий набор.
Ну, это не всегда обязательно. В некоторых случаях достаточно определить строгий тип только в том файле, где инклюдится другой. Зависит от стека вызовов.
LIME пишет:
Как бэ да но какбэ нет смещения данных и значит н кушается память
Не, я не про экономию памяти говорил а лишь обратил внимание на тот факт, что экземпляр создается в любом случае, об этом свидетельствует вызов конструктора.
LIME пишет:
Все эти геты и сеты не более чем латание дыр
Почему латание дыр? В данном случае PDO пытается присвоить значения публичным свойствам одноименным с полями в БД соответствующие значения потому что был использован FETCH_CLASS. Когда он это делает, не находит такие свойства т.к они приватные и вызывается __set. Сами мы явно магию никак не используем. Не сторонник публичных свойств, но их любителям __set можно и не писать, PDO сам все сделает.
LIME пишет:
Запрос в клиентском коде? Ну для примера наверное...
Ну да, это был пример того, что хочет ТС, в более простой форме.
Это опечатка, естественно я имел ввиду, что он будет статичный.
Ну и что Смотрите. У вас так получается 2 запроса. Один с проверкой на существование, другой для получения продукта если он существует. Почему не выберете сразу продукт, вне класса Product, и если результатом будет не false, тогда работать дальше? Присмотритесь к примеру выше.
Prizma пишет:
добавил код трейта Mysql, может еще какие ошибки увидите))
Ну как минимум 3 косяка.
1. Отсутствие возможности определения параметров подключения динамически (нужно передавать их из вне)
2. Синглтон... Статика... жесткие связи в коде, сложно тестируемый код
3. Трейты нельзя протестировать как отдельное целое
Вообщем говорить об ошибках в данном случае можно не мало, если хотите понять ООП, изучайте фреймворки, читайте сурьезные статьи на эту тему Как вариант можете попробовать с S.O.L.I.D как было предложено выше. Из ФВ рекомендую Zend Framework 2