• API для вывода денег с QIWI (перевод на другой QIWI-кошелек)

    @d_garmashev
    Есть API на вывод денег с QIWI Кошелька.
    Как получать токен + описание методов переводов доступно в документации https://developer.qiwi.com/qiwiwallet/qiwicom_ru.html

    Публичное XML API для переводов не поддерживается, только REST, доступные по ссылке на документацию выше.

    Покупка API к QIWI Кошельку сопряжено с риском потерять деньги, так как требует логина и пароля от пользователя и дает полный доступ.
    Ответ написан
    4 комментария
  • Кто должен логировать? Функция или тот, кто её вызывает?

    artemgapchenko
    @artemgapchenko
    То, что вы описали, называется в англоязычной литературе cross-cutting concerns - это такие области кода, которые решают не саму бизнес-задачу, а являются как бы перпендикулярными к ней, и относятся скорее к функционированию системы. Вы правы насчёт того, что добавлять логирование в саму функцию - это, наверное, не совсем правильный выбор, так как во-первых, функция начинает решать две задачи, что сразу же уменьшает время на понимание её работы, а во-вторых, возможно будут варианты вызова функции, при которых её выполнение логировать не обязательно.
    Я бы, возможно, попробовал зайти к этой задаче со стороны паттерна Декоратор (дальше пишу на Java, так как этот язык для меня основной, но принципы должны быть понятны).

    Определяем интерфейс:

    interface ClientHandler {
    	void blockUser(User user);
    	void unblockUser(User user);
    }

    Дальше пишем реализацию, которая будет заниматься блокированием/разблокированием пользователя:

    public final class ClientHandlerImpl implements ClientHandler {
    	public void blockUser(User user) {
    		// Логика блокирования пользователя
    	}
    
    	public void unblockUser(User user) {
    		// Логика разблокирования пользователя
    	}
    }

    А теперь ход конём: пишем декоратор, который будет оборачивать собой написанную нами имплементацию (и в аргументе конструктора пробрасываем ClientHandlerImpl):

    public final class ClientHandlerLoggingDecorator implements ClientHandler {
    	private final ClientHandler handler;
    
    	public ClientHandlerLoggingDecorator(final ClientHandler handler) {
    		this.handler = handler;
    	}
    
    	public void blockUser(User user) {
    		Log.d("User " + user.getName() + " blocked!")
    		handler.blockUser(user);
    	}
    
    	public void unblockUser(User user) {
    		Log.d("User " + user.getName() + " unblocked!")
    		handler.unblockUser(user);
    	}
    }


    Дальше можно будет создать, например, фабрику ClientHandler'ов, которая по запросу будет возвращать нам новый инстанс ClientHandler'а:

    public final class ClientHandlerFactory {
    	public static ClientHandler getClientHandler() {
    		return new ClientHandlerLoggingDecorator(new ClientHandler());
    	}
    }

    Чего мы добились:
    1. Код логирования вынесен из реализации ClientHandler, если вам нужно будет изучить реализацию блокирования/разблокирования, вы просто открываете ClientHandlerImpl, и изучаете её.
    2. (связано с предыдущим пунктом) Реализацию блокирования/разблокирования и логирования теперь можно менять независимо друг от друга.
    3. Логирующее поведение становится скрытым для пользователей ClientHandler - они просто получают новый инстанс при обращении к фабрике, и используют его. Хотите отключить логирование? Меняете реализацию фабрики, и она начинает возвращать ClientHandlerImpl. Хотите сделать это поведение настраиваемым? Пишете дополнительный код, который на старте читает конфигурацию, и начинает использовать либо ту реализацию фабрики, которая возвращает ClientHandler, покрытый декоратором, либо реализацию, которая возвращает голый ClientHandler. Либо же зашиваете этот выбор внутрь самой фабрики.
    Ответ написан
    Комментировать
  • Как разбить большую функцию на несколько мелких?

    Adamos
    @Adamos
    Архитектура измеряется не длиной функций, а их назначением. Функция, выполняющая ровно одну задачу, обычно и не будет длинной.
    Подойдите к вопросу со стороны тестирования. Вас устроит тест этой функции как единого черного ящика? Или у нее есть конкретные части, которые выполняют полноценные подзадачи, под которые хорошо бы иметь отдельный тест на случай, если в функции будут изменения? Если нет и у вас просто однородная простыня - разбивать незачем. Если есть - почему нет?
    Ну, а если вас смущает накопление никому больше не нужных функций - вспомните, что в РНР есть ООП и все это может быть собрано в класс, а нигде больше не используемые функции - сделаны приватными.
    Ответ написан
    Комментировать
  • Как определить дату регистрации профиля ВКонтакте?

    @prineside
    Спам-бот
    vk.com/foaf.php?id=25573397 , где GET[id] - ID страницы пользователя на vk.com

    Возвращает XML. Тех. поддержка сказала, что фича не официальная - значит, может и отпасть. Но стоит уже довольно долго и все эти сайтики с информацией о дате регистрации страниц, скорее всего, к ней подвязаны.

    ID страницы можно узнать через API или с помощью тестовой формы на странице документации методов API (это если пользователь изменил свой адрес страницы и тем самым скрыл ID в адресной строке).

    Как парсить - отдельная тема, скажу только, что дата регистрации лежит в rdf:RDF -> foaf:Person -> ya:created.

    Информация о FOAF: https://ru.wikipedia.org/wiki/FOAF

    Кстати, по той же ссылке можно получить еще некоторую интересную информацию, например, дату последнего изменения страницы.
    Ответ написан
    Комментировать
  • Вопрос по функциям php (аргументы по умолчанию)?

    nazarpc
    @nazarpc
    Open Source enthusiast
    Только указать это значение явно, пропустить никак не получится
    Ответ написан
    Комментировать
  • Как осуществить динамическое расширение массива?

    svd71
    @svd71
    обычно я делеаю такие штуки так:
    i := Length(Eat);
    SetLength(Eat, i+1);
    Eat[i].EatName := Eatname; 
    Eat[i].EatCoun t:= EatCount;
    Ответ написан
    Комментировать
  • Как осуществить динамическое расширение массива?

    @BlueRay
    Если в Delphi индексация массива с нуля (уже не помню, вдруг с единицы), то доступ к последнему элементу осуществляется не через Eat[Length(Eat)], а через Eat[Length(Eat) - 1].
    Ответ написан
    Комментировать
  • Что делать с дублями страниц на сайте?

    Если Вы о СЕО, то на всех дублять прописывать
    <link rel="canonical" href="http://основной адрес страницы" />
    Ответ написан
    Комментировать
  • Ошибка в MySQL и PHP

    @Slko
    C++/C#/Python Developer
    Данный код - идеальный пример, в котором можно эксплуатировать SQL-инъекцию. Используйте параметризированные запросы или экранируйте входные данные.
    А если отвечать конкретно на этот вопрос, то в GET['name'], я полагаю, передаётся helloworld без кавычек и выходит такой SQL-запрос:
    SELECT * FROM news WHERE link = helloworld
    Соответственно, надо добавлять кавычки вокруг "helloworld", потому что без кавычек это интерпретируется как идентификатор столбца, а не как строка.
    Ответ написан
    Комментировать
  • Почему когда работает curl, apache блокирует доступ к хосту?

    fornit1917
    @fornit1917
    Как вариант: если у вас php-сессии хранятся в файлах и в запросах открывается сессия, то проблема может быть в этом.
    Например один процесс апача (тот который использует curl) открывает сессию, затем начинается парсинг. Сессия открыта, файл с ней заблокирован. Вы шлете другой запрос к своему серверу, где тоже открывается сессия, но она не может открыться т.к. файл заблокирован другим процессом, поэтому этот процесс будет висеть, пока процесс-блокировщик не закончит парсить страницу и не закроет сессию.
    Ответ написан
    5 комментариев
  • Как сделать MySQL запрос, что бы получить сгруппированный массив?

    @Masterme
    Нет
    Ответ написан
    Комментировать
  • Передача переменной в exe файл при его скачивании?

    afiskon
    @afiskon

    Если я правильно понял, нужно заменить Laptinius на что-то другое? Тогда делается очень просто. Откройте exe-шник каким-нибудь hex-редактором и найдите смещение этой строки. Перед скачиванием создавайте копию этого файла и по этому смещению пишите другую строку.

    Или, чтобы не было проблем с случае обновления exe-шника, используйте не смещение, а сканируйте файл в поисках этой строки. Будет совсем хорошо, если строка будет длинной и уникальной, типа Wai3AhKukaiQuai1.

    Ответ написан
    Комментировать
  • Передача переменной в exe файл при его скачивании?

    TDz
    @TDz

    Выше товарищ Hint корректно ответил - самый простой способ это дописывать строку в конец файла. Я могу добавить что для этой задачи есть чудесныe модули для nginx, к примеру HttpAdditionModule или HttpEchoModule

    Также популярен способ выдачи .msi файла вместо exe. MSI тоже исполняемый под виндой, но в нём зашиты текстовые блоки которые проще изменять "на лету". Но это в любом случае сложней чем первый способ.

    Если в вашем экзешнике зашита проверка целостности тогда нужно писать скрипт который будет склеивать некий служебный экзешник (чья задача только в распаковке целевого файла и передаче переменной) с переменной и собственно полезным экзешником. Но это уже и проблемы с некоторыми антивирусами, и посложней в реализации.

    Ответ написан
    Комментировать
  • Фильтрация пробела в параметре URL

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР

    К "любознательности" этот вопрос не имеет отношения. А думать, что это каким-либо образом относится к SQL - прямая дорога к инъекции.

    А имеет - к валидации данных и, частично, к юзабилити и СЕО.

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

    Ответ написан
    1 комментарий
  • API для вывода денег с QIWI (перевод на другой QIWI-кошелек)

    @WhiteTigera
    Дожно работать. можно с помощью плагина к FF (https://addons.mozilla.org/ru/firefox/addon/poster/ послать запрос и проверить
    Вот пример запроса/от) вета, по новому API, POST запрос на https://w.qiwi.com/xml/xmlutf.jsp

    Send:
    <?xml version="1.0" encoding="utf-8"?>
    <request>
     <request-type>pay</request-type>
     <terminal-id>1234</terminal-id> -- ид магазина
     <extra name="password">***</extra> -- пароль
     <auth count="1" to-amount="1.00">
    		<payment>
    		 <transaction-number>50</transaction-number> --ид вашего перевода
    		  <from>
    		   <ccy>643</ccy>
    		  </from>
    		  <to>
    		   <amount>1.00</amount> --сумма
    		   <ccy>643</ccy>
    		   <service-id>99</service-id>
    		   <account-number>79168888888</account-number> --кому
    		  </to>
    		 <extra name="comment">test</extra>
    		</payment>
     </auth>
    <extra name="client-software">API example v1.0</extra>
    </request>



    Recieve:
    <response>
    <result-code fatal="false">0</result-code>
    <payment status='50' txn_id='409' transaction-number='50' result-code='0' final-status='false' fatal-error='false' txn-date='11.10.2013 16:59:00'  >
      <from>
        <amount>1.00</amount>
        <ccy>643</ccy>
      </from>
      <to>
        <service-id>99</service-id>
        <amount>1.00</amount>
        <ccy>643</ccy>
        <account-number>79168888888</account-number>
      </to>
    </payment>
    <balances>
    <balance code="643">00.49</balance>
    </balances>
    <f>
    </f>
    </response>



    Если статус платежа от 50 до 60, то платеж прошел (см. status='50' )
    Ответ написан
    2 комментария
  • Именование класса (девушке нужна помощь)?

    Alez
    @Alez
    >девушке нужна помощь
    читер
    Ответ написан
    Комментировать
  • Вопрос по MVC. Где выполнять проверку?

    dizballanze
    @dizballanze
    Software developer at Yandex
    Существует подход thin controllers — that models, согласно которому в контроллере нужно, как можно меньше всего выполнять. В идеале чтобы контроллеры не больше 10 строк были.
    Ответ написан
    1 комментарий
  • Вопрос по MVC. Где выполнять проверку?

    Все что касается валидации / проверки данных должно уходить в модель. Если же вам нужно проверять, валидная корзина (на верхнем более абстрактном уровне), то выполняйте эту проверку в контроллере.

    А насчет различных сообщений — возвращайте из модели различные сообщения в случае неудачи и дальше их обрабатывайте в контроллере, делайте удобные проброски на вьюхи, где уже выводите в зависимости от этого различные наборы красоты :)

    PS удачи и успехов в вашем не легком деле :)
    Ответ написан
    1 комментарий
  • Вопрос по MVC. Где выполнять проверку?

    int03e
    @int03e
    В контроллере смотреть на результат выполнения cart.addProduct (true/false) и выводить ошибку при рендеринге вьюхи, если есть такая необходимость.
    Ответ написан
    7 комментариев