php

Описание: Разработка и отладка приложений. Упор на 3D-графику.

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 6 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#7 dyvniy » Пт, 19 сентября 2014, 10:19:58

Синглертон
http://lifeexample.ru/php-primeryi-skriptov/php-singleton-singlton.html
Спойлер
Только для читателей Lifeexample возможно открыть интернет магазин на Moguta.CMS со скидкой в 15%

<<< XSS уязвимость и защита от XSS || Бесплатная CMS для интернет магазина >>>
PHP Singleton (Синглтон)
26.07.2012
PHP Singleton (Синглтон)
Здравствуйте, уважаемые читатели блога LifeExample, сегодня мы будем разбираться с очередным шаблоном программирования в PHP – Синглтоном (Singleton).

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

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

Концепция шаблона Singleton
Страшное слово синглтон ассоциируемое у меня, по названию, c мелафоном из сериала «Гостья из будущего» (1984 г.), совершенно не имеет никакого сходства с машиной времени.

Singleton – это обычный php класс, в логику работы которого включена проверка на эксклюзивность его создания. Т.е. объект класса, построенный по шаблону синглтона, может быть создан лишь один раз. Все будущие попытки обратиться к его методу или свойству, создав новый объект, будут нейтрализованы логикой его работы и перенаправлены на уже имеющийся экземпляр.

Таким образом, класс, построенный по принципу синглтона, будет защищен от многочисленного создания и дублирования действий при интерпретации кода.

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

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

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

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

Решением этой проблемы как раз и занимается шаблон Singleton.

Обычный пример PHP Singleton
Давайте ознакомимся с концепцией и классическим примером реализации php синглтона. Взгляните на этот код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
class someClass {
protected static $_instance;

private function __construct() {
}

public static function getInstance() {
if (self::$_instance === null) {
self::$_instance = new self;
}

return self::$_instance;
}

private function __clone() {
}

private function __wakeup() {
}
}
?>
В данном коде представлен некоторый класс, в логике работы которого, реализован паттерн – синглтон.

Первым делом объявляется защищенная статическая переменная $_instance, назначением которой является хранение в себе единственного экземпляра данного класса.

Конструктор в синглтоне защищен от публичного вызова, а следовательно исключает дублирование объектов.

Другими словами, если попытаться создать объект (PHP Singleton) класса стандартным образом:

1
obj= new someClass();
то мы получим сообщение об ошибке, в котором сказано, что конструктор доступен только изнутри класса.

1
Call to private someClass::__construct() from invalid context in…
Для того чтобы создать объект нам нужно вызвать статический метод getInstance(); таким образом:

1
someClass::getInstance();
Единственной точкой входа в класс является статическая функция getInstance() цель которой – создать первый и единственный экземпляр класса, записав его в переменную $_instance. При вызове getInstance() функция создает экземпляр класса, а следовательно задействует механизм конструктора.

Неотъемлемой частью синглтона в PHP является объявление приватных магических методов __clone() и _wakeup() , предотвращающих возможные дублирования объекта.

На этом классическое описание модели, во многих ресурсах сети заканчивается. Но остается вопрос, как пользоваться синглтоном в PHP, а главное зачем?

Пока не попробуете на практике, смысла не уловите, поэтому я настоятельно советую вам потратить еще 10 минут своего свободного времени, и посмотреть как можно на практике использовать паттерн Singleton в PHP.

PHP Singleton на примере класса для работы с БД
Если кто-то забыл, или не знает основ для работы с базами данных в php, читайте статью PHP работа с базой данных (Часть 1)

Самым подходящим примером будет маленькая система для работы с БД. Под маленькой системой я подразумеваю три файла :

index.php – точка входа в систему
class.db.php – singleton для работы с БД
class.order.php – некоторый вымышленный класс внутри которого идет работа с БД с помощью синглтона
Первым делом создадим index.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
error_reporting(E_ALL);
require 'class.db.php';

// константы для подключени к БД

define('HOST', 'localhost'); //сервер
define('USER', 'root'); //пользователь
define('PASSWORD', ''); //пароль
define('NAME_BD', 'test');//база

DB::getInstance(); // инициализация экземпляра класса дл работы с БД
//свободное использование класса

//вывод таблицы продуктов
$result=DB::query("SELECT id,product FROM `product`");
echo '<h2>Таблица продуктов:</h2> <table border="1">';
while($obj=DB::fetch_object($result)){
echo '<tr><td>'.$obj->id.'</td><td>'.$obj->product.'</td><tr>';
}
echo '</table>';
В коде index.php подключается файл class.db.php, содержащий реализацию синглтона, и производится инициализация констант для доступа к базе данных, а также инициализация объекта для работы с БД DB::getInstance();.

Примечание! Для более оптимизированной работы с синглтоном, можно внести вызов getInstance(); внутрь используемых классом публичных функций. Это поможет устранить необходимость явного определения экземпляра класса описанным выше методом DB::getInstance();

Далее следует пример работы с классом синглтона, в котором выводится содержимое таблицы product.

Чтобы это все заработало нужно создать файл class.db.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?class DB {

protected static $_instance; //экземпляр объекта

public static function getInstance() { // получить экземпляр данного класса
if (self::$_instance === null) { // если экземпляр данного класса не создан
self::$_instance = new self; // создаем экземпляр данного класса
}
return self::$_instance; // возвращаем экземпляр данного класса
}

private function __construct() { // конструктор отрабатывает один раз при вызове DB::getInstance();
echo "<br/><em>1. Установка соединения с хостом...";
//подключаемся к БД
$this->connect = mysql_connect(HOST, USER, PASSWORD) or die("Невозможно установить соединение".mysql_error());
// выбираем таблицу
echo "<br/>2. Выбор базы...";
mysql_select_db(NAME_BD, $this->connect) or die ("Невозможно выбрать указанную базу".mysql_error());
// устанавливаем кодировку таблицы
echo "<br/>3. Устанавливаем кодировку базы: ";
$this->query('SET names "utf8"');
echo "<br/> Конструктор успешно открыл соединение с БД! и установил кодировку.</em>";

}

private function __clone() { //запрещаем клонирование объекта модификатором private
}

private function __wakeup() {//запрещаем клонирование объекта модификатором private
}

public static function query($sql) {

$obj=self::$_instance;

if(isset($obj->connect)){
$obj->count_sql++;
$start_time_sql = microtime(true);
$result=mysql_query($sql)or die("<br/><span style='color:red'>Ошибка в SQL запросе:</span> ".mysql_error());
$time_sql = microtime(true) - $start_time_sql;
echo "<br/><br/><span style='color:blue'> <span style='color:green'># Запрос номер ".$obj->count_sql.": </span>".$sql."</span> <span style='color:green'>(".round($time_sql,4)." msec )</span>";

return $result;
}
return false;
}

//возвращает запись в виде объекта
public static function fetch_object($object)
{
return @mysql_fetch_object($object);
}

//возвращает запись в виде массива
public static function fetch_array($object)
{
return @mysql_fetch_array($object);
}

//mysql_insert_id() возвращает ID,
//сгенерированный колонкой с AUTO_INCREMENT последним запросом INSERT к серверу
public static function insert_id()
{
return @mysql_insert_id();
}


}
Сей класс является рабочей реализацией паттерна singleton в php, а также наглядно демонстрирует важность единственности объекта. Для тех кто не видит важности поясню: в конструкторе данного класса производится подключение к БД, если убрать логику синглтона, то нерадивые программисты смогут организовать тысячи бессмысленных подключений к БД .

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

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

Кстати, если в местах вывода заменить echo на вывод в файл, то получится наглядный лог запросов.

На этом описание класса предлагаю завершить, но если есть вопросы пишите в комментариях, отвечу.

Теперь файл index.php можно запускать. Ах да, конечно же вам понадобится импортировать дамп тестовой базы, приложенный в исходниках, или обращаться к своей БД :

Наследование Singleton в PHP
Мы уже имеем возможность обращаться к функциям синглтона, теперь попробуем сделать это в отдельном классе Order.

Многие новички делают не правильные выводы относительно данного шаблона программирования и пытаются сделать наследование дочерних классов от синглтона.

При таком подходе теряется весь смысл синглтона как механизма, защищающего дублирование объектов.

Если вы хотите наследовать некоторый класс от синглтона, то в самом синглтоне вам придется открыть публичный доступ к конструктору класса. В противном случае вы будете получать ошибку:

1
Call to private someClass::__construct() from invalid context in…
А открыв публичный доступ ломается вся защита.

Поэтому наследовать PHP Singleton, не рационально и бессмысленно, так как можно обращаться к классу синглтона из любой точки программы, инициализировав его единожды в index.php.

В следующем классе это наглядно продемонстрировано:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
//попробуем создать класс и внутри него работать с БД
class Order {
public function getOrderList(){

// $result=DB::query("INSERT `order` SET id=4,content=777");
$result=DB::query("SELECT id,content FROM `order` where id=4");

$html='<h2>Таблица заказов:</h2> <table border="1">';
while($obj=DB::fetch_object($result)){
$html.='<tr><td>'.$obj->id.'</td><td>'.$obj->content.'</td><tr>';
}
$html.='</table>';
return $html;
}
}
Создайте class.order.php и вставьте в него вышеприведенный код. В конец файла index.php допишите следующее:

1
2
3
4
5
6
7
8
require 'class.order.php';

$order = new Order();
echo $order->getOrderList();

//попробуем создать новый экземпляр DB
echo "<span style='color:red'>";
$DB2 = new DB();
Запустив приложение вы должны будете наблюдать такую картину:

Пример синглтона в php
Ошибка в конце страницы сгенерирована намеренно, для демонстрации защиты от дублирования PHP Singleton. Избавиться от ошибки можно, удалив последнюю строку:

1
$DB2 = new DB();
На этом, я предлагаю завершить наше знакомство с очередным шаблоном программирования PHP Singleton‘ом, надеюсь, материал окажется вам полезен. Подписывайтесь на RSS обновления и не пропустите следующей статьи о другом не мало известном паттерне программирования Registry.
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 6 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#8 dyvniy » Пт, 19 сентября 2014, 10:31:15

Подключание к PayPal
http://lifeexample.ru/php-primeryi-skriptov/integ ... -paypal-prostoy-php-klass.html
Спойлер
Интеграция PayPal, простой PHP класс
18.12.2013
Интеграция PayPal. Простой PHP класс
самой надежной в мире системой электронных оплат.

PayPal (англ. «приятель, помогающий расплатиться») — крупнейший оператор электронных денежных средств. Позволяет клиентам оплачивать счета и покупки, отправлять и принимать денежные переводы. С октября 2002 года является подразделением компании eBay. По состоянию на 2012 год PayPal работает в 193 странах (хотя не во всех предоставляется полный набор услуг), имеет более 137 млн зарегистрированных пользователей, работает с 26 национальными валютами.

Просмотрев некоторые примеры в сети, я был поражен их несостоятельностью. Представленные ниже классы для интеграции PayPal на сайт, не являются сложными, но соответствуют моему требованию о покупке товара поштучно. Код не идеален, но вы всегда можете доработать его самостоятельно.

Я решил подойти к вопросу обработки IPN разбив процессы на объекты, отвечающие за выполнение логических под-задач для того, чтобы было понятно программистам знакомым с объектно-ориентированным программирование. ( Даже если вы не знакомы, я надеюсь, что моя статья даст вам возможность увидеть преимущества и лучше понять методологию, сэкономив много времени на будущее.)

Интеграция PayPal
Для того чтобы не упустить важные детали собственной настройки ниже я собираюсь копировать вставлять свой код и изменять соответствующую информацию. Конечно, статья из-за этого увеличится и будет создаваться впечатление сборки кода, но я считаю, что в самом коде содержится необходимая информация, и заранее приношу свои извинения, поскольку вам придется скопировать несколько файлов из этой статьи, если вы их собираетесь использовать для своего проекта и вставить их в собственный проект.

Мое решение разделяет процесс на пять объектов:

payPalController – этот класс занимается обработкой логики не связанных с IPN частей PayPal процессов. Они занимается проверкой двойных транзакций, отправляемых PayPal, и проверяет факт совершения IPN транзакции именно по продукту с моего сайта. В таком случае, покупка добавляется в базу данных, а покупатель получает email.
payPalIpn – место проведения обработки IPN. Очень важно!
rmwStoreDB – с помощью этого класса транзакции добавляются в базу данных с моей стороны.

<!doctype html public '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>
<html>
<head>
<title>Some Title</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Generator" content="Alleycode HTML Editor">
<meta name="Description" content="Working Code">
<meta name="Keywords" content="Working Code">
</head>

<body>
<?php

require_once ("../phpPayPalController.php");
$ppc = new payPalController();
$ppc->setTesting(false);
$ppc->setLogging(false);
$ppc->processPayPalIpnPayment();
?>

</body>
Как вы видите payPalController – единственный класс, о котором нужно знать странице. Контроллер настроит остальные классы самостоятельно:

<?php
require_once("phpPayPalIpnClass.php");
require_once("phpLoggerClass.php");
require_once("phpRmwStoreDbActions.php");
require_once("phpMyMailClass.php");


class payPalController {
private $db;
private $logger;
private $testing;


function __construct() {
$this->logger = new myLogger();
$this->logger->setLogFile("logger.txt");
$this->logger->setLogging(false);
$this->db = new rmwStoreDB();
$this->db->setLogger($this->logger);
$this->testing = false;
}


function setTesting($state) {
$this->testing = $state;
$this->logger->setLogging($state);
}


function setLogging($state) { $this->logger->setLogging($state); }


function processPayPalIpnPayment() {
$processor = new payPalIpn();
$processor->setTesting($this->testing);
$processor->setLogger($this->logger);
$this->logger->log("Processing a payment.\r\n");

if (!$processor->processPost()) return;
if ($this->duplicateTransaction()) return;
if (!$this->verify()) return;
if (!$this->addOrderToDatabase()) return;
$this->sendProduct();
}


private function duplicateTransaction() {
$ret = false;
if ($this->db->itemExists("orders", "payPalTransId",
$_POST['txn_id'])) {
$this->logger->log("Transaction: " . $_POST['txn_id']
. " exists\r\n");
$ret = true;
}

else {
$this->logger->log("Transaction: " . $_POST['txn_id'] .
" does not exist\r\n");
}
return $ret;
}


private function verify() {

if (!$this->db->itemExists("products", "id", $_POST
['item_number'])) {
$this->logger->log("Item number: " . $_POST['item_number']
. " doesn't exist in database\r\n");
return false;
}
else {
$this->logger->log("Item number: " . $_POST['item_number'] .
" exists in database\r\n");
}

$this->dbPrice = $this->db->getCellValue("price",
"products", "id", $_POST['item_number']);
if ($_POST['mc_gross'] < $this->dbPrice) {
$this->logger->log("Payment received (" . $_POST
['mc_gross'] . ") less than item price. ("
. $this->dbPrice . "\r\n");
return false;
}
else {
$this->logger->log("Adequate payment received (" . $_POST
['mc_gross'] . ").\r\n");
}

if ($_POST['mc_currency'] != "USD") {
$this->logger->log("Paid in non-US funds - need to investigate.\r\n");
return false;
}

else {
$this->logger->log("US Currency received - OK.\r\n");
}

if ($_POST['receiver_email'] !=
"emailAddress@someplace.com"
&& $_POST['receiver_email'] !=
"sandboxEmailAddress@someplace.com") {
$this->logger->log("Incorrect receiver email received ("
. $_POST['receiver_email'] . ")\r\n");
return false;
}
else {
$this->logger->log("Correct email received (
" . $_POST['receiver_email'] . ")\r\n");
}


if ($_POST['payment_status'] != "Completed") {
$this->logger->log("Payment incomplete from PayPal\r\n");
return false;
}
return true;
}

private function addOrderToDatabase() {

$this->logger->log("Updating database.\r\n");
$this->db->addOrUpdateUser();
$this->db->addOrder();
return true;
}


private function sendProduct() {
$mailHandler = new myMailer();
$mailHandler->setLogger($this->logger);

if ($this->testing) {
$mailTo = 'emailAddress@someplace.com';
}
else {
$mailTo = $_POST['payer_email'];
}


if ($_POST['item_number'] == "XXXX" || $_POST
['item_number'] == "XXXY") {
if ($_POST['option_selection1'] == 'EPub') {
$this->logger->log("Sending EPub to " . $mailTo .
"\r\n");
$mailHandler->sendEbook('EPub', $mailTo);
}
else if ($_POST['option_selection1'] == 'MOBI') {
$this->logger->log("Sending MOBI to " . $mailTo . "\r\n");
$mailHandler->sendEbook('MOBI', $mailTo);
}
else {
$this->logger->log("SOMETHING WRONG - Not EPub or MOBI!\r\n");
}
}
}

}
?>
Теперь перейдем к классу payPalIpn. Как было сказано ранее, этот класс ответственен за обработку IPN и отправку корректных ответов на PayPal.

require_once("db_config.php");
require_once("phpLoggerClass.php");


class rmwStoreDB {

private $loggerC;
private $lastRowC;

function setlogger(mylogger $logFile) { $this->loggerC = $logFile; }


function tellDb($sql) {
$ret = mysql_query($sql);
if (!$ret) {
$this->loggerC->log(
"DATABASE ERROR:\r\n" . mysql_error() . "\r\n" .
"Query: " . HtmlEntities($sql));
die();
}
return $ret;
}


function itemExists($table, $column, $value) {
$rows = $this->tellDb("Select * from " . $table . " where " .
$column . " = '" . $value . "'");
$lastRowC = mysql_fetch_array($rows);
if ($lastRowC) return true;
return false;
}


function getCellValue($what, $table, $column, $theId) {
$rows = $this->tellDb("Select " . $what . " from " . $table .
" where " . $column . " = " . $theId);
$row = mysql_fetch_array($rows);
if ($row) return $row['price'];
else return 0.00;
}


function addOrUpdateUser() {

$rows = $this->tellDb("Select * from customers where email = '" .
$_POST['payer_email'] . "'");

$row = mysql_fetch_array($rows);
if (!$row) {
$this->loggerC->log("Adding user to database");
$this->addUser();
}
else {
$this->loggerC->log("User already exists in DB.\r\n");

$this->updateUser($row);
}
}


private function addUser() {
$cmd = "Insert into customers (firstName, lastName, shippingName, email, " .
"addressLine1, city, state, zipCode, country) values ('"
. $_POST['first_name'] . "', '" .
$_POST['last_name'] . "', '" .
$_POST['address_name'] . "', '" .
$_POST['payer_email'] . "', '" .
$_POST['address_street'] . "', '" .
$_POST['address_city'] . "', '" .
$_POST['address_state'] . "', '" .
$_POST['address_zip'] . "', '" .
$_POST['address_country'] . "')";

$this->tellDb($cmd);

$this->loggerC->log("Added: '" . $_POST['first_name'] .
"', '" . $_POST['last_name'] .
"', '" . $_POST['address_name'] .
"', '" . $_POST['payer_email'] .
"', '" . $_POST['address_street'] .
"', '" . $_POST['address_city'] .
"', '" . $_POST['address_state'] .
"', '" . $_POST['address_zip'] .
"', '" . $_POST['address_country'] .
"')");
}


private function updateUser(array $row) {

if ($row['firstName'] != $_POST['first_name'] ||
$row['lastName'] != $_POST['last_name'] ||
$row['shippingName'] != $_POST['address_name'] ||
$row['email'] != $_POST['payer_email'] ||
$row['addressLine1'] != $_POST['address_street'] ||
$row['city'] != $_POST['address_city'] ||
$row['state'] != $_POST['address_state'] ||
$row['zipCode'] != $_POST['address_zip'] ||
$row['country'] != $_POST['address_country']) {


$cmd = "UPDATE customers SET ";
$cmd .= "firstName = '" . $_POST['first_name'] . "', ";
$cmd .= "lastName = '" . $_POST['last_name'] . "', ";
$cmd .= "shippingName = '" . $_POST['address_name'] . "', ";
$cmd .= "addressLine1 = '" . $_POST['address_street'] . "', ";
$cmd .= "city = '" . $_POST['address_city'] . "', ";
$cmd .= "state = '" . $_POST['address_state'] . "', ";
$cmd .= "zipCode = '" . $_POST['address_zip'] . "', ";
$cmd .= "country = '" . $_POST['address_country'] . "' ";
$cmd .= "WHERE email = '" . $_POST['payer_email'] . "'";
$this->loggerC->log("\r\nChanging user with email " . $_POST['payer_email'] . "\r\n");

$old = $row['firstName'] . ", " . $row['lastName'] .
", " . $row['shippingName'] . ", " .
$row['email'] . ", " .
$row['addressLine1'] . ", " . $row['city'] .
", " .$row['state'] . ", " .
$row['zipCode'] . ", " . $row['country'] .
"\r\n\r\n";

$this->loggerC->log($old);
$this->loggerC->log($cmd . "\r\n");

$this->tellDb($cmd);
}
}


function addOrder() {

$cmd = "Select id from customers where email = '" .
$_POST['payer_email'] . "'";

$rows = $this->tellDb($cmd);
$row = mysql_fetch_array($rows);
if (!$row) {
$this->loggerC->log("HUGE PROBLEM! CUSTOMER ID NOT FOUND -" .
" ABORTING\r\n");
die();
}
$id = $row['id'];
$theDate = date('F j, Y, g:i a');
$tz = date('T');
$ppID = $_POST['txn_id'];
$grossPay = $_POST['payment_gross'];
$shipping = $_POST['shipping'];
$cmd = "Insert into orders (customer, date, timeZone, payPalTransId, " .
"grossPmt, shipping) values ('$id', '" .
"$theDate', '$tz', '$ppID', '" .
"$grossPay', '$shipping')";

$this->tellDb($cmd);
$this->loggerC->log("Inserting order into orders table:\r\n" . $cmd .
"\r\n\r\n");



$cmd = "Select id from orders where payPalTransId = '$ppID'";
$rows = $this->tellDb($cmd);
$row = mysql_fetch_array($rows);

if (!$row) {
$this->loggerC->log("HUGE PROBLEM! ORDER ID NOT FOUND -" .
" ABORTING\r\n");
die();
}

$id = $row['id'];

$itemNum = $_POST['item_number'];
$qty = $_POST['quantity'];
$info = $_POST['option_selection1'];
$cmd = "Insert into orderItems (orderNumber, item, quantity, extraInfo)" .
" values('$id', '$itemNum', '$qty'," .
" '$info')";
$this->loggerC->log(
"Inserting into order items:\r\n" . $cmd . "\r\n");
$this->tellDb($cmd);
}

}
?>
Ура! Следующие классы PHP для интеграции PayPal намного меньше предыдущих! Первый класс – почтового клиента. Понятное дело, что при его простоте можно сказать, что он должен быть более ярким и отправлять получше чем сейчас отформатированные HTML ответы на покупки. Но всему свое время.

<?php

require_once("emailPassword.php");
require_once("phpLoggerClass.php");
require_once("/path_to/swift_required.php");

class myMailer {

private $myEmail;
private $logger;


function __construct() {
$this->myEmail = "someone@somewhere.com";
}


function setLogger(myLogger &$logFile) { $this->logger = $logFile; }


function sendEbook($ebookType, $mailTo) {

$this->mailWithAttachment($fileName, $path, $mailTo, $this->myEmail, $from,
$replyTo, $subject, $msg);
}


private function mailWithAttachment($filename, $path, $mailTo, $from_mail, $from_name,
$replyto, $subject, $message) {


$transport = Swift_SmtpTransport::newInstance('mailServer.com', 465, 'ssl')
->setUsername(hiddenEmailAccount())
->setPassword(hiddenEmailPassword())
;
$mailer = Swift_Mailer::newInstance($transport);
$message = Swift_Message::newInstance()
->setSubject($subject)
->setFrom(array($from_mail => $from_name))
->setTo(array($mailTo))
->setBody($message)
//->addPart('<p>Here is the message itself</p>', 'text/html')
->attach(Swift_Attachment::fromPath($path.$filename))
;
$this->logger->forceLog("Sending " . $filename . " to " . $mailTo .
" : ");
$result = $mailer->send($message);
$this->logger->forceLog("Result = " . $result . "\r\n");
}
}
?>
Последним идет класс логов:

<?php

class myLogger {

private $fileNameC;
private $doLoggingC;

function __construct() {
$this->fileNameC = "log.txt";
$this->doLoggingC = true;
}

function setLogFile($fileName) { $this->fileNameC = $fileName; }
function setLogging($state) { $this->doLoggingC = $state; }

function log($msg) {
if ($this->doLoggingC == true) {
file_put_contents($this->fileNameC, $msg, FILE_APPEND);
}
}

function forceLog($msg) {
file_put_contents($this->fileNameC, $msg, FILE_APPEND);
}

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

Содержание db_config.php файла следующее. За исключением того, что здесь не представлены реальные пользователи, пароли и базы данных!

$db_con = mysql_connect("localhost", "theUser", "thePassword", true) or die(mysql_error());
$db_selected = mysql_select_db("theDatabase") or die(mysql_error());
И наконец, файл с паролем email (“emailPassword.php” в представленном выше коде):

<?php

function hiddenEmailAccount() {
return "someone@somewhere.com";
}

function hiddenEmailPassword() {
return "thePassword";
}

?>
Надеюсь, представленная информация была полезной, если вы собираетесь заниматься интеграцией PayPal с помощью простого PHP класса. Спасибо за того, что прочитали мою статью и удачного вам программирования. Если вам удастся, что-то улучшить, буду рад увидеть улучшения в комментариях.
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 6 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#9 dyvniy » Ср, 19 ноября 2014, 11:20:06

Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 6 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#10 dyvniy » Вс, 5 апреля 2015, 07:59:22

инъекция
https://www.xaker.name/forvb/showthread.php?t=13504
Потенциально опасными функциями являются:
eval(),
preg_replace() (с модификатором «e»),
require_once(),
include_once(),
include(),
require(),
create_function().
PHP-инъекция становится возможной, если входные параметры принимаются и используются без проверки.
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 6 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#11 dyvniy » Пн, 6 апреля 2015, 11:27:36

aptitude install php5-gd php5-imagick
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 6 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#12 dyvniy » Ср, 11 ноября 2015, 07:36:28

загрузка на сервер №2
http://javascript.ru/forum/dom-window/28174-zagru ... -server-sredstvami-iframe.html
Спойлер
10.05.2012, 12:14
lamer lamer вне форума
Профессор
Отправить личное сообщение для lamer Посмотреть профиль Найти все сообщения от lamer
Регистрация: 08.02.2012
Сообщений: 214

Загрузка файла на другой сервер средствами iframe
Здравствуйте.
Появилась необходимость загружать файлы на второй сервер принимая их на первом.
т.е. юзер загружает файл на server-1, а файл загружается на server-2

Читал что можно подобное реализовать без перезагрузки страницы методом Remote Scripting используя iframe. Но конкретных примеров с подробным описанием так и не нашел.

Может кто то встречал в инете и может кинуть линк или выложить в топе с подробным описанием ? Думаю полезно было бы не только мне.
Заранее спасибо.
Ответить с цитированием
#2 (permalink)
Старый 10.05.2012, 16:38
lamer lamer вне форума
Профессор
Отправить личное сообщение для lamer Посмотреть профиль Найти все сообщения от lamer
Регистрация: 08.02.2012
Сообщений: 214

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

index.html на первом сервере - server-1.com

Код: Выделить всё

<html>
<
head>
<
meta charset="utf-8">
    <
title>Облако тегов</title>
    <
script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
    <script type="text/javascript">  
        function hideBtn(){
            $('#upload').hide();
            $('#res').html("Идет загрузка файла");
        }
        function handleResponse(mes) {
            $('#upload').show();
            if (mes.errors != null) {
                $('#res').html("Возникли ошибки во время загрузки файла: " + mes.errors);
            }  
            else {
                $('#res').html("Файл " + mes.name + " загружен");  
            }  
        }
    </script>
</head>
<body>
<form action="http://server-2.com/uploads/upload.php" method="post" target="hiddenframe" enctype="multipart/form-data" onsubmit="hideBtn();">
<input type="file" id="userfile" name="userfile" />
<input type="submit" name="upload" id="upload" value="Загрузить" />
</form>
<div id="res"></div>
<iframe id="hiddenframe" name="hiddenframe" style="width:0px; height:0px; border:0px"></iframe>
</body>
</html>


Файл upload.php на втором сервере - server-2.com

Код: Выделить всё

<?php
if(isset($_POST['upload'])){
    
//Список разрешенных файлов
    
$whitelist = array(".gif"".jpeg"".png");        
    
$data = array();
    
$error true;
    
//Проверяем разрешение файла
    
foreach  ($whitelist as  $item) {
        if(
preg_match("/$item\$/i",$_FILES['userfile']['name'])) $error false;
    }
    
//если нет ошибок, грузим файл
    
if(!$error) {
        
$folder =  '.../uploads/';//директория в которую будет загружен файл
        
$uploadedFile =  $folder.basename($_FILES['userfile']['name']);
        if(
is_uploaded_file($_FILES['userfile']['tmp_name'])){
            if(
move_uploaded_file($_FILES['userfile']['tmp_name'],$uploadedFile)){
                
$data $_FILES['userfile'];
           }
            else { 
                
$data['errors'] = "Во время загрузки файла произошла ошибка";
            }
        }
        else { 
            
$data['errors'] = "Файл не  загружен";
        }
   }
    else{
        
$data['errors'] = 'Вы загружаете запрещенный тип файла';
    }

    
//Формируем js-файл   
    
$res '<script type="text/javascript">';
    
$res .= "var data = new Object;";
    foreach(
$data as $key => $value){
        
$res .= 'data.'.$key.' = "'.$value.'";';
    }
    
$res .= 'window.parent.handleResponse(data);';
    
$res .= "</script>";
    echo 
$res;
}
else{
    die(
"ERROR");
}
?>


Но проблема в том что если передавать файлы на второй сервер то статус загрузки файла так и остается висеть: Идет загрузка файла хотя файл давно загружен на сервер.
т.е. не получается без перезагрузки страницы получить ответ от второго сервера что файл загружен.

Прочел на одном ресурсе:
Цитата:
возникает проблема с Cross-Domain-Request, если вы имеете доступ к скрипту loader.php на другом сервере, то есть возможность правильно заполнить Cross-Origin заголовки и тогда все запуститься само
Читал про crossdomain.xml прописывал заголовки:
<cross-domain-policy>
<allow-access-from domain="*" to-ports="80"/>
</cross-domain-policy>


Все равно так и висит строка Идет загрузка файла
Изображение


Название раздела: Программирование (под Desktop и Android)
Описание: Разработка и отладка приложений. Упор на 3D-графику.

Быстрый ответ


Введите код в точности так, как вы его видите. Регистр символов не имеет значения.
Код подтверждения
:) ;) :hihi: :P :hah: :haha: :angel: :( :st: :_( :cool: 8-| :beee: :ham: :rrr: :grr: :* :secret: :stupid: :music: Ещё смайлики…
   

Вернуться в «Программирование (под Desktop и Android)»

Кто сейчас на форуме (по активности за 15 минут)

Сейчас этот раздел просматривают: 9 гостей