{"id":169537,"date":"2013-02-16T02:54:03","date_gmt":"2013-02-15T22:54:03","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=169537"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=169537","title":{"rendered":"<span class=\"post_title\">HOWTO: \u041e\u0434\u043d\u0430 \u0438\u0437 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u041c\u043e\u0434\u0435\u043b\u0438 (MVC) \u0432 Zend Framework<\/span>"},"content":{"rendered":"<div class=\"content html_format\">   \t\u041d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u043d\u0430\u0432\u0435\u044f\u043d\u043e <a href=\"http:\/\/habrahabr.ru\/qa\/34735\/\">habrahabr.ru\/qa\/34735\/<\/a> \u0438 <a href=\"http:\/\/habrahabr.ru\/qa\/32135\/\">habrahabr.ru\/qa\/32135\/<\/a> \u0432\u043e\u043f\u0440\u043e\u0441\u0430\u043c\u0438, \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0441\u043c\u043e\u0433 \u043d\u0430\u0439\u0442\u0438 \u043f\u043e\u043b\u043d\u043e\u0439 \u0438 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438, \u0447\u0435\u0433\u043e \u043e\u0447\u0435\u043d\u044c \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u043b\u043e. \u042f \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u0447\u0442\u043e \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u0430 \u0438 \u0434\u0440\u0443\u0433\u0438\u043c. <\/p>\n<p>  \u041f\u0440\u043e\u0435\u043a\u0442, \u043d\u0430 \u0447\u044c\u044e \u0434\u043e\u043b\u044e \u043f\u0430\u043b \u0432\u044b\u0431\u043e\u0440 \u0432 \u0432\u0438\u0434\u0435 ZF \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u043b \u0438\u0437 \u0441\u0435\u0431\u044f \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 (\u0430\u0434\u0430\u043f\u0442\u0438\u0432\u043d\u044b\u0439 \u0434\u0438\u0437\u0430\u0439\u043d \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043d\u044c\u044e\u0430\u043d\u0441\u0430\u043c\u0438) + \u0410\u041f\u0418 \u0434\u043b\u044f \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. <br \/>  \u041a\u043e\u043b\u043b\u0435\u0433\u0438\u0430\u043b\u044c\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u043e-\u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0434\u0438\u043d\u043e\u0435 \u0410\u041f\u0418, \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0449\u0430\u0442\u044c\u0441\u044f \u0438 \u0441\u0430\u0439\u0442, \u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. <\/p>\n<p>  \u041d\u0430 \u044d\u0442\u043e\u043c, \u0434\u0443\u043c\u0430\u044e, \u043f\u0440\u0435\u043b\u044e\u0434\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u044c \u0438 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0441\u0430\u043c\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u043c\u0443.<br \/>  <a name=\"habracut\"><\/a><br \/>  \u0421\u0442\u0430\u0442\u044c\u044e \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u043b \u043d\u0430 2 \u0447\u0430\u0441\u0442\u0438. <a href=\"#theory\">\u0412 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0442\u0435\u043e\u0440\u0438\u0438, \u043c\u044b\u0441\u043b\u0435\u0439 \u0438 \u043e\u0442\u0441\u044b\u043b\u043e\u043a \u043a \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430\u043c. <a href=\"#examples\">\u0412\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a> \u044f \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e (\u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 \u043a\u043e\u0434\u0430) \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c, \u043a\u0430\u043a \u044f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b \u0441\u0432\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b. <br \/>  <a name=\"theory\"><\/a>  <\/p>\n<h4>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0442\u0435\u043e\u0440\u0438\u0438<\/h4>\n<p>  <\/p>\n<h5>\u041d\u0430\u0447\u0430\u043b\u043e<\/h5>\n<p>  Zend Framework \u2014 \u043d\u0435 \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u043e\u0440\u043e\u0433\u0430 \u0432\u0445\u043e\u0434\u0430. \u042f \u043f\u043e\u0442\u0440\u0430\u0442\u0438\u043b \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0447\u0442\u043e\u0431\u044b \u0432\u043d\u0438\u043a\u043d\u0443\u0442\u044c \u0432 \u0435\u0433\u043e \u0438\u0434\u0435\u043e\u043b\u043e\u0433\u0438\u044e, \u043d\u043e \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e, \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0448\u0430\u0433 \u043e\u0436\u0438\u0434\u0430\u0435\u043c, \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c \u0438 \u043b\u043e\u0433\u0438\u0447\u0435\u043d. <\/p>\n<p>  \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e <a href=\"http:\/\/framework.zend.com\/manual\/1.12\/en\/manual.html\">\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>, \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u0435\u0441\u0442\u0430\u0445 \u043e\u043d\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0443\u0436\u0430\u0442\u0430 (\u043a\u043e\u043b\u043b\u0435\u0433\u0438 \u0434\u0430\u0436\u0435 \u0434\u0435\u043b\u0438\u043a\u0430\u0442\u043d\u043e \u043f\u0440\u043e\u0437\u0432\u0430\u043b\u0438 \u0435\u0435 \u00ab\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0432 \u0441\u0442\u0438\u043b\u0435 \u0422\u0432\u0438\u00bb), \u0438 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0431\u0440\u0430\u0442\u044c \u0438\u0437 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432. <\/p>\n<p>  \u0421\u0440\u0430\u0437\u0443 \u0445\u043e\u0447\u0443 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0442\u0435\u0445, \u043a\u0442\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043e \u043c\u043e\u043d\u0441\u0442\u0440\u0443\u043e\u0437\u043d\u043e\u0441\u0442\u0438 \u0441\u0435\u0433\u043e \u0447\u0443\u0434\u0430 \u2014 \u0434\u0430, \u0437\u0435\u043d\u0434 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0430\u044f, \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u043d\u0430\u044f \u043f\u0443\u0448\u043a\u0430, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434\u2026 \u043f\u043e \u0432\u043e\u0440\u043e\u0431\u044c\u044f\u043c \u0442\u043e \u0438 \u043d\u0435 \u043a \u0447\u0435\u043c\u0443\u2026 \u041d\u043e \u043f\u0440\u0438\u0441\u043c\u043e\u0442\u0440\u0435\u0432\u0448\u0438\u0441\u044c \u0438 \u0438\u0437\u0443\u0447\u0438\u0432 \u0435\u0433\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0434\u0430\u0436\u0435 \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u043d\u043e, \u044f \u043c\u043e\u0433\u0443 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c, \u0447\u0442\u043e \u043a\u0430\u043b\u0438\u0431\u0440 \u044d\u0442\u043e\u0439 \u043f\u0443\u0448\u043a\u0438 \u043e\u0447\u0435\u043d\u044c \u0434\u0430\u0436\u0435 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f. \u0415\u0441\u0442\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043d\u0435\u043f\u043b\u043e\u0445\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 autoloader, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u043a\u043b\u0430\u0441\u0441\u043e\u0432.<\/p>\n<p>  \u0421\u043e\u0431\u0440\u0430\u0432 \u043a\u0430\u0440\u043a\u0430\u0441 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (quick start) \u043d\u0430\u0447\u0430\u043b \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u043f\u0440\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0439 \u0438 best practice \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u0430 ZF (\u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u0430\u0441\u044c <a href=\"http:\/\/www.slideshare.net\/weierophinney\/playdoh-modelling-your-objects-1766001\">\u043f\u0440\u0435\u0437\u0435\u043d\u0442\u0430\u0446\u0438\u044f<\/a>, \u043f\u043e\u0447\u0435\u0440\u043f\u043d\u0443\u043b \u0438\u0437 \u043d\u0435\u0435 \u043c\u043d\u043e\u0433\u043e \u043c\u044b\u0441\u043b\u0435\u0439, \u043f\u043e \u0442\u0435\u043a\u0441\u0442\u0443 \u043d\u0430 \u043d\u0435\u0435 \u0435\u0449\u0435 \u0431\u0443\u0434\u0443\u0442 \u0441\u0441\u044b\u043b\u043a\u0438).<\/p>\n<h5>\u041c\u043e\u0434\u0435\u043b\u044c \u0432 MVC<\/h5>\n<p>  \u041c\u043d\u043e\u0433\u0438\u0435 \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 \u0438 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442 \u043c\u043e\u0434\u0435\u043b\u044c \u043a\u0430\u043a \u0441\u043f\u043e\u0441\u043e\u0431 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0434\u0430\u043d\u043d\u044b\u043c \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0432\u0435\u0440\u043d\u043e. \u041c\u043e\u0434\u0435\u043b\u044c \u2014 \u044d\u0442\u043e \u043d\u0435 \u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u0438 \u0434\u0430\u0436\u0435 \u043d\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u0430. \u0414\u0430\u043d\u043d\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u044c \u0438\u0437 \u0440\u0430\u0437\u043d\u044b\u0445 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432.<br \/>  \u042f \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b \u043c\u043e\u0434\u0435\u043b\u044c \u043a\u0430\u043a \u043c\u043d\u043e\u0433\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u0443\u044e \u043f\u0440\u043e\u0441\u043b\u043e\u0439\u043a\u0443 \u0438 \u0432\u044b\u0434\u0435\u043b\u0438\u043b \u0434\u043b\u044f \u0441\u0435\u0431\u044f 3 \u0441\u043b\u043e\u044f:  <\/p>\n<ul>\n<li>Domain Model <\/li>\n<li>Data Mapper <\/li>\n<li>Data Access Layer (DAL)<\/li>\n<\/ul>\n<p>  <b>Domain Model<\/b> \u2014 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0433\u0435\u0442\u0442\u0435\u0440\u044b, \u0441\u0435\u0442\u0442\u0435\u0440\u044b, \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 (behavior). <a href=\"http:\/\/msdn.microsoft.com\/en-us\/magazine\/ee236415.aspx\">\u0411\u044b\u0442\u0443\u0435\u0442 \u043c\u043d\u0435\u043d\u0438\u0435<\/a>, \u0447\u0442\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u0432 \u043f\u0440\u043e\u0441\u043b\u043e\u0439\u043a\u0443 DomainEvents, \u0438 \u044d\u0442\u043e \u0435\u0441\u0442\u044c \u043d\u0435\u0447\u0442\u043e \u0438\u043d\u043e\u0435 \u043a\u0430\u043a <a href=\"http:\/\/design-pattern.ru\/patterns\/table-data-gateway.html\">Table Data Gateway pattern<\/a>.<br \/>  \u042d\u0442\u043e\u0442 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0432 \u043c\u043e\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u043e \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u0445 (\u0438 \u043c\u0435\u0441\u0442\u0430\u0445) \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>  <b>Data Mapper<\/b> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u0440\u043e\u0441\u043b\u043e\u0439\u043a\u0443, \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u0443\u044e \u0434\u043b\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0442\u0440\u0430\u043d\u0441\u0444\u0435\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0442 \u0443\u0440\u043e\u0432\u043d\u044f \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0433\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a \u043d\u0438\u0437\u043a\u043e\u043c\u0443 \u0443\u0440\u043e\u0432\u043d\u044e. <\/p>\n<p>  <b>DAL<\/b> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u0440\u044f\u043c\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0443 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445. \u0422\u0430\u043c \u043c\u043e\u0436\u043d\u043e \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u0442\u044c SQL \u043a\u043e\u0434 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0440\u0435\u043b\u0435\u0441\u0442\u0438 \u0436\u0438\u0437\u043d\u0438. \u0412 ZF \u0440\u043e\u043b\u044c \u044d\u0442\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 Zend_Db_Table \u0438 \u0435\u0433\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u043d\u044b\u0435. <\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043d\u0435\u0448\u043d\u0438\u0435 ORM, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 Doctrine, \u0442\u043e \u043e\u043d\u0430 \u0432\u043f\u043e\u043b\u043d\u0435 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0443\u0440\u043e\u0432\u043d\u0438 \u0438 \u043e\u0431\u043b\u0435\u0433\u0447\u0430\u0435\u0442 \u0436\u0438\u0437\u043d\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430. \u0422\u0430\u043a \u043a\u0430\u043a \u044f \u0441\u0435\u0431\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b \u0446\u0435\u043b\u044c \u0441\u043a\u043e\u0440\u0435\u0435 \u00ab\u0438\u0437\u0443\u0447\u0430\u0442\u044c \u0441 \u043f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u0435\u043c\u00bb, \u044f \u043d\u0435 \u0441\u0442\u0430\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0435 ORM \u0438 \u0440\u0435\u0448\u0438\u043b \u0441\u0434\u0435\u043b\u0430\u0442\u044c <s>\u0441\u0432\u043e\u0439 \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434<\/s> \u0441\u0432\u043e\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e.<br \/>  <a name=\"examples\"><\/a>  <\/p>\n<h4>HowTo<\/h4>\n<p>  <\/p>\n<h6>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/h6>\n<p>  \u0420\u0435\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0430\u044f\u0441\u044f \u043a\u0430\u0440\u0442\u0438\u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b:<\/p>\n<pre><code>application\/ \tcontrollers\/ \t\tIndexController.php \t\tFooController.php \tmodels\/ \t\tAbstract\/ \t\t\tAbstractMapper.php \t\t\tAbstractModel.php \t\tDBTable\/ \t\t\tFooTable.php \t\t\tDeviceTable.php \t\tMapper\/ \t\t\tFooMapper.php \t\t\tDeviceMapper.php \t\tFoo.php \t\tDevice.php \tservices\/ \t\tDeviceService.php \t\tFooService.php \tviews\/ <\/code><\/pre>\n<p>  <\/p>\n<h5>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 <\/h5>\n<p>  \u042f \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u043a \u043f\u043e\u0434\u0445\u043e\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u043e\u043d\u043a\u0438\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440, \u0430 \u0432\u0435\u0441\u044c \u0431\u0438\u0437\u043d\u0435\u0441 \u0432\u044b\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u0432 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0438 \u043c\u043e\u0434\u0435\u043b\u0438. \u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u043c\u043e\u0441\u0442\u044c \u043a\u043e\u0434\u0430, \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0432\u043d\u0435\u0441\u0435\u043d\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432 \u043b\u043e\u0433\u0438\u043a\u0443. <br \/>  \u041f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u0440\u0438\u043c\u0435\u0440 \u00ab\u043d\u0435\u0439\u0442\u0440\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e\u00bb \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e, \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044e \u0438 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u044d\u0442\u0438\u043c\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430\u043c\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">class DeviceapiController extends Zend_Controller_Action { \tpublic function init() \t{ \t\t$this-&gt;_helper-&gt;viewRenderer-&gt;setNoRender(true); \t}  \t\/** \t * Login user from API Request \t * @method POST \t * @param json rawBody {&quot;data&quot;:{&quot;login&quot;: &quot;admin&quot;, &quot;password&quot;: &quot;password&quot;}} \t * @param string login in JSON \t * @param string password in JSON \t * \t * @return string SecretKey \t * @return HTTP STATUS 200 if ok  \t * @return HTTP STATUS 400 if fields doesn't valid   \t * @return HTTP STATUS 409 if user already exist \t *\/ \tpublic function loginAction() \t{ \t\t$request    = $this-&gt;getRequest(); \t\t$data\t    = $request-&gt;getRawBody(); \t\t \t\tif ($data) { \t\t\t\/\/ decode from json params \t\t\t$params = Zend_Json::decode($data); \t\t\t \t\t\t$result = Application_Service_DeviceService::login($params); \t\t\tif (!is_null($result['secretKey'])) { \t\t\t\t$this-&gt;getResponse() \t\t\t\t\t-&gt;setHttpResponseCode(200) \t\t\t\t\t-&gt;setHeader('Content-type', 'application\/json', true) \t\t\t\t\t-&gt;setBody(Zend_Json::encode($result)); \t\t\t\t \t\t\t\t$this-&gt;_setSecretKeyToCookies($result['secretKey']); \t\t\t\treturn; \t\t\t} \t\t\t$this-&gt;getResponse() \t\t\t\t-&gt;setHttpResponseCode(401); \t\t\treturn; \t\t} \t\t \t\t$this-&gt;getResponse() \t\t\t-&gt;setHttpResponseCode(405); \t\treturn; \t}  \t\/** \t * Profile from API Request \t * \t * @method GET \t * @param Request Header Cookie secretKey \t * \t * @return json string {&quot;id&quot;:&quot;&quot;,&quot;email&quot;:&quot;&quot;,&quot;realName&quot;:&quot;&quot;} \t * @return HTTP STATUS 200 OK \t *\/ \tpublic function profileAction() \t{ \t\t$cookies = $this-&gt;getRequest()-&gt;getCookie(); \t\tif (!isset($cookies['secretKey']) || (!Application_Service_DeviceService::isAuthenticated($cookies['secretKey']))) { \t\t\t$this-&gt;getResponse() \t\t\t\t-&gt;setHttpResponseCode(401) \t\t\t\t-&gt;setHeader('Content-Type', 'application\/json') \t\t\t\t-&gt;setBody(Zend_Json::encode(array(&quot;message&quot; =&gt; &quot;Unauthorized&quot;))); \t\t\treturn; \t\t} \t\t \t\t$result = Application_Service_DeviceService::getProfile($cookies['secretKey'])-&gt;toArray(); \t\t \t\tunset($result['password']); \t\tunset($result['passwordSalt']); \t\t \t\t$this-&gt;getResponse() \t\t\t-&gt;setHttpResponseCode(200) \t\t\t-&gt;setHeader('Content-type', 'application\/json', true) \t\t\t-&gt;setBody(Zend_Json::encode($result)); \t\treturn; \t} \t \t\/** \t * Logout from API Request \t * @method POST \t * @param Request Header Cookie secretKey \t *  \t * @return HTTP STATUS 200 OK \t *\/ \tpublic function logoutAction() \t{ \t\t$cookies = $this-&gt;getRequest()-&gt;getCookie();  \t\tif ($cookies['secretKey']) { \t\t\t$device = new Application_Model_Device(); \t\t\t$device-&gt;deleteByKey($cookies['secretKey']); \t\t\t$this-&gt;_setSecretKeyToCookies($cookies['secretKey'], -1);  \t\t\tif(Zend_Auth::getInstance()-&gt;hasIdentity()) { \t\t\t\tZend_Auth::getInstance()-&gt;clearIdentity(); \t\t\t} \t\t} \t        $this-&gt;getResponse() \t\t\t-&gt;setHttpResponseCode(200); \t\treturn; \t} \t \t\/** \t * Signup user from API Request \t * @method POST \t * @param  json string {&quot;email&quot;: &quot;&quot;, &quot;password&quot;: &quot;&quot;, \u201crealName\u201d: \u201c\u201d} \t * \t * @return string SecretKey \t * @return HTTP STATUS 201 Created \t * @return HTTP STATUS 400 Bad request \t * @return HTTP STATUS 409 Conflict - user already exist \t *\/ \tpublic function signupAction() \t{ \t\t$request    = $this-&gt;getRequest(); \t\t$data\t    = $request-&gt;getRawBody();  \t\t\/\/ decode from json params \t\t$params = Zend_Json::decode($data);  \t\t$email = $params['email']; \t\t$name = $params['realName']; \t\t$password = $params['password'];  \t\t$err = array(); \t\tif (!isset($email) || !isset($name) || !isset($password) || (filter_var($email, FILTER_VALIDATE_EMAIL)==FALSE)) \t\t{ \t\t\tif (!isset($email)) { \t\t\t\t$err['email'] = &quot;Email is missing&quot;; \t\t\t} \t\t\tif (!isset($name)) { \t\t\t\t$err['name'] = &quot;Name is missing&quot;; \t\t\t} \t\t\tif (!isset($password)) { \t\t\t\t$err['password'] = &quot;Password are missing&quot;; \t\t\t} \t\t\tif (filter_var($email, FILTER_VALIDATE_EMAIL)==FALSE) { \t\t\t\t$err['valid_email'] = &quot;Email is not valid&quot;; \t\t\t} \t\t} \t\t \t\tif (!empty($err)) { \t\t\t$this-&gt;getResponse() \t\t\t\t-&gt;setHttpResponseCode(400) \t\t\t\t-&gt;setBody(Zend_Json::encode(array (&quot;invalid&quot; =&gt; $err))); \t\t\treturn; \t\t} \t\t \t\t$service = new Application_Service_DeviceService(); \t\t$params = array(&quot;email&quot; =&gt; $email, &quot;username&quot; =&gt; $name, &quot;password&quot; =&gt; $password); \t\t \t\ttry { \t\t\t$result = $service-&gt;signup($params); \t\t} catch (Zend_Exception_UserAlreadyExist $e) { \t\t\t$this-&gt;getResponse() \t\t\t\t-&gt;setHttpResponseCode(409) \t\t\t\t-&gt;setBody(Zend_Json::encode(array(&quot;message&quot; =&gt; &quot;User already exist&quot;))); \t\t\treturn; \t\t} \t\t \t\t$this-&gt;getResponse() \t\t\t-&gt;setHttpResponseCode(201) \t\t\t-&gt;setHeader('Content-type', 'application\/json', true) \t\t\t-&gt;setBody(Zend_Json::encode($result));  \t\t$this-&gt;_setSecretKeyToCookies($result['secretKey']); \t\treturn; \t}  \t\/** \t * Protected local method to set Secretkey to Cookies \t * @param string $secretKey \t * @param int | null $timeFlg \t *\/ \tprotected function _setSecretKeyToCookies($secretKey,$timeFlg = 1) { \t\t\t$cookie = new Zend_Http_Header_SetCookie(); \t\t\t$cookie-&gt;setName('secretKey') \t\t\t\t-&gt;setValue($secretKey) \t\t\t\t-&gt;setPath('\/') \t\t\t\t-&gt;setExpires(time() + (1* 365 * 24 * 60 * 60)*$timeFlg); \t\t\t$this-&gt;getResponse()-&gt;setRawHeader($cookie); \t\t\treturn; \t} } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0440\u043e\u043b\u044c \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u0430 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u0440\u043e\u0443\u0442\u0435\u0440\u0430 \u043d\u0430 \u0431\u0438\u0437\u043d\u0435\u0441 (\u0432\u044b\u0437\u043e\u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432) \u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u0432\u0435\u0442\u043e\u0432. \u0412 \u043c\u043e\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u043d\u0435 \u0431\u044b\u043b\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u0410\u041f\u0418. \u0412 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445, \u043a\u043e\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043e\u0434\u043d\u0443 \u0438 \u0442\u0443 \u0436\u0435 \u043b\u043e\u0433\u0438\u043a\u0443, \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u0438\u043f\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0432\u044b\u0434\u0430\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u0432 \u0440\u0430\u0437\u043d\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435, \u0443\u0434\u043e\u0431\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c content switcher. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e, \u043a\u043e\u0433\u0434\u0430 \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u0437\u0430\u043f\u0440\u043e\u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0441\u0430\u0439\u0442\u043e\u043c, \u0434\u043b\u044f \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0430\u044f\u043a\u0441 \u0432\u044b\u0437\u043e\u0432\u043e\u0432, \u0438\u043b\u0438 \u043a\u043e\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0442\u0434\u0430\u0442\u044c \u0432 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0444\u043e\u0440\u043c\u0430\u0442\u0430\u0445 (\u043b\u0438\u0431\u043e \u0432 JSON, \u043b\u0438\u0431\u043e \u0432 XML, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440) \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 Content-Type \u0437\u0430\u043f\u0440\u043e\u0441\u0430. <br \/>  \u041d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u044d\u0442\u043e \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b. <br \/>  \u0422\u0430\u043a\u0438\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c, \u0442\u0435\u0441\u0442\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u044e\u0442 \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b, \u043a\u0430\u043a \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u0412 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u044f \u043d\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u043b \u0442\u0430\u043a\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0438\u043a\u0438, \u043a\u0430\u043a TDD, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0435\u0441\u0442\u044b \u043f\u0438\u0441\u0430\u043b \u0443\u0436\u0435 \u043f\u043e \u0433\u043e\u0442\u043e\u0432\u044b\u043c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430\u043c. \u042d\u0442\u043e \u043f\u043e\u043c\u043e\u0433\u043b\u043e \u0432\u044b\u044f\u0432\u0438\u0442\u044c \u043f\u0430\u0440\u0443 \u0443\u0437\u043a\u0438\u0445 \u043c\u0435\u0441\u0442 \u0438 \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0431\u0430\u0433\u043e\u0432. <br \/>  \u0412 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043c\u043e\u0438\u0445 \u0441\u043b\u043e\u0432 \u043e \u043b\u0435\u0433\u043a\u043e\u0439 \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c\u043e\u0441\u0442\u0438 \u0442\u0430\u043a\u0438\u0445 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432 \u043d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u0435\u0441\u0442\u043e\u0432. <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0422\u0435\u0441\u0442\u044b \u0434\u043b\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430  \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442  \u0442\u0430\u043a<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">class LoginControllerTest extends Zend_Test_PHPUnit_ControllerTestCase {     \/*      * Fixtures:      * User with `email@example.com` and `password`     *\/     public function setUp()     {         $this-&gt;bootstrap = new Zend_Application(APPLICATION_ENV, APPLICATION_PATH . '\/configs\/application.ini');         parent::setUp();     }      public function testSuccessfulLoginAction()     {     \t$request = $this-&gt;getRequest();      \t$email = 'email@example.com';     \t     \t$request-&gt;     \t\tsetMethod('POST')-&gt;     \t\tsetHeader('Content-Type', 'application\/json')-&gt;     \t\tsetRawBody(Zend_Json::encode(array(     \t\t\t'email' =&gt; $email,     \t\t\t'password' =&gt; 'password',     \t\t)));     \t$this-&gt;dispatch('\/login');     \t$this-&gt;assertResponseCode(200);      \t$this-&gt;assertNotRedirect();     \t$this-&gt;assertHeaderContains('Content-Type', 'application\/json');     \t$data = $this-&gt;getResponse()-&gt;getBody();     \t$data = Zend_Json::decode($data, true);     \t     \t$this-&gt;assertArrayHasKey('secretKey', $data);     \t$this-&gt;resetRequest()     \t\t-&gt;resetResponse();        \t\/\/ Test logout     \t$request-&gt; \t    \tsetMethod('POST')-&gt; \t    \tsetHeader('Content-Type', 'application\/json')-&gt; \t    \tsetCookie('secretKey', $data['secretKey']);     \t$this-&gt;dispatch('\/logout');     \t$this-&gt;assertResponseCode(200);     \t     \t$this-&gt;resetRequest()     \t\t-&gt;resetResponse();     }          public function testLoginWithEmptyParamsAction()     {     \t$request = $this-&gt;getRequest();          \t$request-&gt;     \t\tsetMethod('POST')-&gt;     \t\tsetHeader('Content-Type', 'application\/json')-&gt;     \t\tsetRawBody(Zend_Json::encode(array(     \t\t\t'email' =&gt; '',     \t\t\t'password' =&gt; '',     \t)));     \t$this-&gt;dispatch('\/login');     \t$this-&gt;assertResponseCode(401);      \t     \t$this-&gt;resetRequest()     \t\t-&gt;resetResponse();     }          public function testLoginWithoutParamsAction()     {     \t$request = $this-&gt;getRequest();          \t$request-&gt;     \t\tsetMethod('POST')-&gt;     \t\tsetHeader('Content-Type', 'application\/json');     \t     \t$this-&gt;dispatch('\/login');     \t$this-&gt;assertResponseCode(405);     \t     \t$this-&gt;resetRequest()     \t\t-&gt;resetResponse();     }          public function testSignupAction()     {         $request = $this-&gt;getRequest();                  $email = &quot;newemail_&quot;.substr(MD5(uniqid(rand(), true)), 0, 12).&quot;@&quot;.substr(MD5(uniqid(rand(), true)), 0, 5).&quot;.com&quot;;                  $request-&gt;             setMethod('POST')-&gt;             setHeader('Content-Type', 'application\/json')-&gt;             setRawBody(Zend_Json::encode(array(                 'email' =&gt; $email,                 'password' =&gt; 'password',                 'realName' =&gt; 'John Dow',             )));         $this-&gt;dispatch('\/signup');         $this-&gt;assertResponseCode(201);         $this-&gt;assertHeaderContains('Content-Type', 'application\/json');         $data = json_decode($this-&gt;getResponse()-&gt;outputBody(), true);         $this-&gt;assertArrayHasKey('secretKey', $data);         $secretKey = $data['secretKey'];         $this-&gt;assertArrayHasKey('user', $data);          $this-&gt;resetRequest()              -&gt;resetResponse();          $request-&gt;             setMethod('POST')-&gt;             setHeader('Content-Type', 'application\/json')-&gt;             setRawBody(json_encode(array(                 'email' =&gt; '2',                 'password' =&gt; '11',                 'realName' =&gt; '23s',             )));         $this-&gt;dispatch('\/signup');         $this-&gt;assertResponseCode(400);         $data = json_decode($this-&gt;getResponse()-&gt;outputBody(), true);         $this-&gt;assertArrayHasKey('invalid', $data);         $invalid = $data['invalid'];         $this-&gt;assertArrayHasKey('email', $invalid);         $this-&gt;assertArrayHasKey('password', $invalid);                  $this-&gt;resetRequest()              -&gt;resetResponse();     }          public function testAlreadyExistUserSignup()      {     \t$request = $this-&gt;getRequest();     \t     \t$request-&gt; \t    \tsetMethod('POST')-&gt; \t    \tsetHeader('Content-Type', 'application\/json')-&gt; \t    \tsetRawBody(Zend_Json::encode(array( \t    \t\t\t'email' =&gt; 'email@example.com', \t    \t\t\t'password' =&gt; 'password', \t    \t\t\t'realName' =&gt; 'John Dow', \t    \t)));     \t$this-&gt;dispatch('\/signup');     \t$this-&gt;assertResponseCode(409);     \t     \t$this-&gt;resetRequest()     \t\t-&gt;resetResponse();     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0412 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u0441\u0430\u043c \u0431\u0438\u0437\u043d\u0435\u0441. \u041c\u0435\u0442\u043e\u0434\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u044f \u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438. \u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u043b \u043c\u043d\u0435 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043b\u0438\u0448\u043d\u0438\u0439 \u0440\u0430\u0437 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0438 \u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u043e\u0442 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u0434\u0440\u0443\u0433 \u043e\u0442 \u0434\u0440\u0443\u0433\u0430, \u0447\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u043e\u0431\u043b\u0435\u0433\u0447\u0430\u0435\u0442 \u0438\u0445 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440, \u0432\u043d\u0435\u0441\u0435\u043d\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439, \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438. <br \/>  \u0422\u0430\u043a\u0436\u0435 \u0441\u0442\u043e\u0438\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e-\u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u0430\u0441\u0441\u0438\u0432\u044b), \u0430 \u0438\u0445 \u0443\u043f\u0430\u043a\u043e\u0432\u043a\u043e\u0439 \u0432 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442, \u0443\u0436\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440. \u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u0435\u0441\u043b\u0438 \u0437\u0430\u0432\u0442\u0440\u0430 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0444\u043e\u0440\u043c\u0430\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u043c\u044b \u044d\u0442\u043e \u0441\u043c\u043e\u0436\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c <s>\u043b\u0435\u0433\u043a\u0438\u043c \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435\u043c \u0440\u0443\u043a\u0438<\/s> \u00ab\u0431\u0435\u0437 \u043b\u0438\u0448\u043d\u0435\u0439 \u043a\u0440\u043e\u0432\u0438\u00bb.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041f\u0440\u0438\u043c\u0435\u0440 \u0441\u0435\u0440\u0432\u0438\u0441\u0430<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">class Application_Service_DeviceService { \tpublic static function login (array $params)  \t{ \t\tif (!empty($params) && !empty($params['email']) && !empty($params['password'])) \t\t{\t \t\t\t$user = new Application_Model_User(); \t\t\t$device = new Application_Model_Device(); \t\t\t$adapter = new Zend_Auth_Adapter_DbTable( \t\t\t\t\tZend_Controller_Front::getInstance()-&gt;getParam('bootstrap')-&gt;getPluginResource(&quot;db&quot;)-&gt;getDbAdapter(), \t\t\t\t\t'user', \t\t\t\t\t'email', \t\t\t\t\t'password', \t\t\t\t\t'MD5(CONCAT(?, passwordSalt,&quot;' \/\/MD5(\u043f\u0430\u0440\u043e\u043b\u044c + \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0445\u044d\u0448 + \u043e\u0431\u0449\u0438\u0439 \u0445\u044d\u0448) \t\t\t\t\t. Zend_Controller_Front::getInstance()-&gt;getParam('bootstrap')-&gt;getOption('salt') . '&quot;))' \t\t\t); \t\t\t\/\/\u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \t\t\t$adapter-&gt;setIdentity($params[&quot;email&quot;]); \t\t\t\/\/\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438\u0437 Zend_Registry::get('authQuery') \t\t\t$adapter-&gt;setCredential($params[&quot;password&quot;]);  \t\t\t$auth = Zend_Auth::getInstance(); \t\t\tif ($auth-&gt;authenticate($adapter)-&gt;isValid()) \/\/\u0443\u0441\u043f\u0435\u0448\u043d\u0430\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \t\t\t{ \t\t\t\t$id = $user-&gt;getCurrentUserId(); \t\t\t\t$secretKey = $user-&gt;generateSecretKey(); \t\t\t\t \t\t\t\ttry { \t\t\t\t\t$device-&gt;userId = $id; \t\t\t\t\t$device-&gt;secretKey = $secretKey; \t\t\t\t\t$device-&gt;lastUsage = time(); \t\t\t\t\t$device-&gt;save(); \t\t\t\t} catch (Exception $e) { \t\t\t\t\tthrow new Exception(&quot;Couldn't save with error &quot;.$e); \t\t\t\t} \t\t\t\t \t\t\t\t$user-&gt;loadById($id); \t\t\t\t \t\t\t\treturn array(&quot;secretKey&quot; =&gt; $secretKey, &quot;user&quot; =&gt; array(&quot;email&quot; =&gt; $user-&gt;{Application_Model_User::ATTRIBUTE_EMAIL}, &quot;realName&quot; =&gt; $user-&gt;{Application_Model_User::ATTRIBUTE_REALNAME}, &quot;id&quot; =&gt; $user-&gt;{Application_Model_User::ATTRIBUTE_ID})); \t\t\t} \t\t} \t\treturn NULL; \t} \t \tpublic function signup (array $params) { \t\t\/\/\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \t\t$user = new Application_Model_User(); \t\t \t\tif ($user-&gt;findExistUserByEmail($params['email']))  \t\t{ \t\t\tthrow new Zend_Exception_UserAlreadyExist(); \t\t}  \t\t \t\t$user-&gt;email = $params['email']; \t\t$user-&gt;realName = $params['username']; \t\t$user-&gt;passwordSalt = $user-&gt;generatePwdSalt(); \t\t$user-&gt;password = $user-&gt;generatePwd($params['password']); \t\t$user-&gt;save(); \t\treturn $this-&gt;login($params); \t} <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e \u0438\u0437 \u043a\u043e\u0434\u0430, \u0432 \u0441\u0435\u0440\u0432\u0438\u0441\u0435, \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438, \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043c\u043e\u0434\u0435\u043b\u0435\u0439, \u0438\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0438\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 \u0438 \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438.<br \/>  \u0414\u0430\u043b\u0435\u0435, \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u0430\u043c\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u044b \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u043b\u0430 \u043d\u0430\u0448\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0438 \u0438\u0445 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 \u043c\u043e\u0434\u0435\u043b\u0438<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">class Application_Model_Device extends Application_Model_Abstract_AbstractModel { \tconst ATTRIBUTE_ID \t\t\t= &quot;id&quot;; \tconst ATTRIBUTE_USER_ID \t        = &quot;userId&quot;; \tconst ATTRIBUTE_SECRET_KEY \t= &quot;secretKey&quot;; \tconst ATTRIBUTE_LAST_USAGE \t= &quot;lastUsage&quot;;  \tprotected \t$_id, \t\t\t\t$_userId, \t\t\t\t$_secretKey, \t\t\t\t$_lastUsage;  \tpublic function __construct(array $options = null, $mapper = null) \t{ \t\t\/\/ for future decorate \t\tif (is_null($mapper)) $this-&gt;_mapper = new Application_Model_DeviceMapper(); \t\telse $this-&gt;_mapper = $mapper;  \t\tif (is_array($options)) { \t\t\t$this-&gt;setOptions($options); \t\t} \t}  \t\/** \t * Wrapper block \t *\/ \tpublic function fromProps() { \t\treturn $data = array( \t\t\t\tself::ATTRIBUTE_USER_ID =&gt; $this-&gt;userId, \t\t\t\tself::ATTRIBUTE_SECRET_KEY =&gt; $this-&gt;secretKey, \t\t\t\tself::ATTRIBUTE_LAST_USAGE =&gt; $this-&gt;lastUsage, \t\t); \t}  \t\/* \t * Start describe behaivors of object \t *\/ \tpublic function getDeviceByKey ($key) { \t\treturn $this-&gt;_mapper-&gt;findByKey($key); \t} \t \tpublic function deleteByKey($key) { \t\treturn $this-&gt;_mapper-&gt;deleteByCriteria('secretKey', $key); \t} } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0411\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u043c\u0435\u0442\u043e\u0434\u0430 \u043c\u043e\u0434\u0435\u043b\u0438<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">        \/** \t * Delete File in DB and unlink physical file \t * \t *\/ \tpublic function deleteFile() \t{ \t\t$id = $this-&gt;id; \t\tif (empty($id)) { \t\t\tthrow new Exception('Invalid id'); \t\t\treturn false; \t\t} \t\t$imageFile = UPLOAD_PATH.'\/'.$this-&gt;{self::ATTRIBUTE_REAL_NAME}; \t\t$thImageFile = THUMB_PATH.'\/'.$this-&gt;{self::ATTRIBUTE_TH_NAME}; \t\t\/\/ \u0423\u0434\u0430\u043b\u044f\u0435\u043c \u044d\u0442\u0443 \u0437\u0430\u043f\u0438\u0441\u044c \u0438\u0437 \u0411\u0414 \t\t \t\t$this-&gt;_mapper-&gt;deleteById($id); \t\t\/\/ \u0423\u0434\u0430\u043b\u044f\u0435\u043c \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0444\u0430\u0439\u043b \t\tunlink($imageFile); \t\tunlink($thImageFile); \t} <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043d\u0430\u0448\u0430 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 (\u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0430) \u0438 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0438\u0445 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c, \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u043d\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u0438 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u044b\u0437\u043e\u0432\u043e\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0438\u0437 \u043c\u0430\u043f\u043f\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0436\u0435 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435\u043c. \u041f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0437\u0430\u0432\u0442\u0440\u0430 \u043c\u044b \u0440\u0435\u0448\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e NoSQL \u0431\u0430\u0437\u0443, \u0438\u043b\u0438 \u043d\u0430\u0447\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u044d\u0448, \u0442\u043e \u043d\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u0435\u043a\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0415\u0449\u0435 \u0440\u0430\u0437 \u0445\u043e\u0447\u0443 \u0441\u043e\u0441\u043b\u0430\u0442\u044c\u0441\u044f \u043d\u0430 <a href=\"http:\/\/www.slideshare.net\/weierophinney\/playdoh-modelling-your-objects-1766001\">\u043f\u0440\u0435\u0437\u0435\u043d\u0442\u0430\u0446\u0438\u044e<\/a>, \u0433\u0434\u0435 \u043e\u0447\u0435\u043d\u044c \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0432\u0441\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430. <br \/>  \u041f\u043e\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u0441\u044f \u0433\u043b\u0443\u0431\u0436\u0435. <br \/>  \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0443\u0440\u043e\u0432\u043d\u0435\u043c \u0432 \u043c\u043e\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0430\u043f\u043f\u0435\u0440. \u0415\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u2014 \u043f\u0440\u043e\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441 \u043e\u0442 \u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u043e \u0443\u0440\u043e\u0432\u043d\u044f DAL. \u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043d\u0430 \u044d\u0442\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c Table Data Gateway pattern.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041f\u0440\u0438\u043c\u0435\u0440 \u043c\u0430\u043f\u043f\u0435\u0440\u0430<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">class Application_Model_DeviceMapper extends Application_Model_Abstract_AbstractMapper { \tconst MODEL_TABLE = &quot;Application_Model_DBTable_DeviceTable&quot;; \tconst MODEL_CLASS = &quot;Application_Model_Device&quot;;  \t\/** \t * Get DBTable \t * \t * @return string $dbTable return current dbTable object \t *\/ \tpublic function getDbTable() \t{ \t\tif (null === $this-&gt;_dbTable) { \t\t\t$this-&gt;setDbTable(self::MODEL_TABLE); \t\t} \t\treturn $this-&gt;_dbTable; \t}  \tpublic function _getModel() { \t\treturn new Application_Model_Device(); \t}  \tpublic function update(array $data, $where) \t{ \t\t\/\/ add a timestamp \t\tif (empty($data['updated'])) { \t\t\t$data['updated'] = time(); \t\t} \t\treturn parent::update($data, $where); \t}  \t\/** \t * @param string $key \t * @throws Zend_Exception_Unauthtorize \t *\/ \tpublic function findByKey($key) \t{ \t\t$result = $this-&gt;getDbTable()-&gt;fetchRow($this-&gt;getDbTable()-&gt;select()-&gt;where(&quot;secretKey = ?&quot;, $key)); \t\tif (0 == count($result)) { \t\t\tthrow  new Zend_Exception_Unauthtorize(); \t\t} \t\treturn $result; \t} } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0412 \u0440\u0430\u043c\u043a\u0430\u0445 \u0441\u0432\u043e\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u044f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u043c\u0430\u043f\u043f\u0435\u0440 \u2014 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 MySql \u0431\u0430\u0437\u043e\u0439, \u043d\u043e \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0430 \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u044d\u0448\u0435\u043c, \u0438 \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u044b\u0441\u043b\u044c \u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 \u0440\u044f\u0434 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043d\u0430 NoSQL. \u0414\u043b\u044f \u043c\u0435\u043d\u044f \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0437\u043d\u0430\u0447\u0430\u0442\u044c \u043b\u0438\u0448\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0434\u0435\u043a\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043a\u043e\u0434\u0430. \u0422\u0435\u0441\u0442\u044b \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043d\u0435 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f (\u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \ud83d\ude42 )<br \/>  \u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e \u0438\u0437 \u043a\u043e\u0434\u0430, \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u043f\u043f\u0435\u0440 \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a \u043a\u043b\u0430\u0441\u0441\u0443 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u2014 DAL. <br \/>  \u0414\u043b\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0441\u043b\u043e\u0439\u043a\u0438 \u044f \u043d\u0435 \u043f\u0440\u0438\u0434\u0443\u043c\u044b\u0432\u0430\u043b \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u043e\u0432\u043e\u0433\u043e \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 Zend.<br \/>  \u0421\u0430\u043c \u043a\u043b\u0430\u0441\u0441 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432\u0435\u0441\u044c\u043c\u0430 \u043d\u0435 \u0437\u0430\u043c\u044b\u0441\u043b\u043e\u0432\u0430\u0442\u043e:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043b\u0430\u0441\u0441 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0434\u0430\u043d\u043d\u044b\u043c (\u0443\u0440\u043e\u0432\u0435\u043d\u044c DAL)<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">class Application_Model_DBTable_DeviceTable extends Zend_Db_Table_Abstract { \tprotected $_name = 'deviceKey'; \tprotected $_primary = 'id'; \t \tprotected $_referenceMap    = array( \t\t\t'Token' =&gt; array( \t\t\t\t\t'columns'           =&gt; 'userId', \t\t\t\t\t'refTableClass'     =&gt; 'Application_Model_DBTable_UserTable', \t\t\t\t\t'refColumns'        =&gt; 'id', \t\t\t\t\t'onDelete'      \t=&gt; self::CASCADE, \t\t\t\t\t'onUpdate'      \t=&gt; self::CASCADE, \t\t\t)); \t \tpublic function __construct($config = array()) { \t\t$this-&gt;_setAdapter(Zend_Db_Table::getDefaultAdapter()); \t\tparent::__construct(); \t} } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0415\u0441\u043b\u0438 \u0437\u0430\u0433\u043b\u044f\u043d\u0443\u0442\u044c \u0432 \u043c\u0430\u043d\u0443\u0430\u043b\u044b Zend Framework, \u0442\u043e \u043b\u0435\u0433\u043a\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e\u0442 (\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e\u0442 \u0443\u0440\u043e\u0432\u0435\u043d\u044c) \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u043e\u0434\u0435\u043b\u0438 (\u0441\u043c. \u043c\u0430\u043d\u0443\u0430\u043b\u044b + Quick Start).<br \/>  \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043c\u0430\u043f\u043f\u0435\u0440\u0430 \u0438 \u043c\u043e\u0434\u0435\u043b\u0438, \u043d\u043e \u0438\u0445 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e.<br \/>  \u0412 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0445\u043e\u0447\u0443 \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e Zend_Db_Table \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043b\u0438\u0431\u043e \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0430\u0445, \u043b\u0438\u0431\u043e \u0432 \u0432\u0438\u0434\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0442\u0438\u043f\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0442\u0438\u043f\u0443 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u043d\u0430\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0438\u0437 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u044d\u0442\u0438 \u043c\u0435\u0442\u043e\u0434\u044b. <br \/>  \u0414\u043b\u044f \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c\u044b\u0445 \u0438\u0437 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449 \u0434\u0430\u043d\u043d\u044b\u0445, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u0438\u0445 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b, \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u043c\u043e\u0434\u0435\u043b\u0438(ORM).<\/p>\n<h4>\u0420\u0435\u0437\u044e\u043c\u0435<\/h4>\n<p>  \u042d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435\u0439 \u0441 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u044b\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043a\u043e\u0434\u0430 \u044f \u043d\u0435 \u043f\u044b\u0442\u0430\u044e\u0441\u044c \u0432\u0441\u0435\u043c \u043d\u0430\u0432\u044f\u0437\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434 \u0438\u043b\u0438 \u0436\u0435 \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c ZF1, \u0430 \u0432\u0442\u043e\u0440\u0443\u044e \u0432\u0435\u0442\u043a\u0443 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430, \u0431\u043e\u043b\u0435\u0435 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e, \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0434\u043b\u044f \u0441\u0432\u0435\u0442\u043b\u043e\u0433\u043e \u0431\u0443\u0434\u0443\u0449\u0435\u0433\u043e. \u0414\u0430, \u043c\u044b \u044d\u0432\u043e\u043b\u044e\u0446\u0438\u043e\u043d\u0438\u0440\u0443\u0435\u043c, \u0440\u0430\u0441\u0442\u0435\u043c \u0438 \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u043c\u0441\u044f, \u043d\u043e \u043e\u0431\u0449\u0438\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u044b, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0435, \u043e\u043d\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b \u0432\u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430. <\/p>\n<p>  \u041d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0435 \u043c\u043d\u043e\u044e \u0432\u044b\u0448\u0435, \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u043e\u0435 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u0432 \u043c\u0430\u043d\u0443\u0430\u043b\u0430\u0445. \u0422\u0430\u043a\u0436\u0435 \u043d\u0435\u0438\u0437\u0431\u0435\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u0438\u0434\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u0433\u043b\u0443\u0431\u043e\u043a\u0430\u044f \u043f\u0440\u043e\u0431\u0440\u043e\u0441\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u043d\u0443\u0442\u0440\u044c. <br \/>  \u042d\u0442\u043e, \u0431\u0435\u0441\u0441\u043f\u043e\u0440\u043d\u043e, \u043c\u0438\u043d\u0443\u0441\u044b. <br \/>  \u0422\u0435\u043f\u0435\u0440\u044c \u043e \u043f\u043b\u044e\u0441\u0430\u0445.   <\/p>\n<ul>\n<li>\u041c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u044b\u0439 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0449\u0435 \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f, \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u0435\u0435 \u0438 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c \u043e\u0448\u0438\u0431\u043e\u043a \u0432 \u043d\u0435\u043c \u0431\u0443\u0434\u0435\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043c\u0435\u043d\u044c\u0448\u0435.<\/li>\n<li>\u0413\u0438\u0431\u043a\u043e\u0441\u0442\u044c, \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u043e\u0441\u0442\u044c. \u0414\u043b\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043b\u0438\u0448\u044c \u0434\u0435\u043a\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434.<\/li>\n<li>\u0420\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u00ab\u0437\u043e\u043d \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438\u00bb \u043c\u0435\u0436\u0434\u0443 \u0443\u0440\u043e\u0432\u043d\u044f\u043c\u0438. <\/li>\n<\/ul>\n<p>  \u041a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043d\u0430\u0441 \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0441\u0430\u043c \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u043a\u0430\u043a\u0443\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c. \u042f \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u043f\u0438\u0441\u0430\u043b \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043b\u044e\u0441\u043e\u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u043f\u0435\u0440\u0435\u0432\u0435\u0448\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0438\u043d\u0443\u0441\u043e\u0432 (\u0433\u043e\u0432\u043e\u0440\u044e \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0441\u0435\u0431\u044f \u0438 \u043c\u043e\u0435\u0433\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430). <a href=\"http:\/\/stackoverflow.com\/questions\/1063664\/zend-framework-orm-style-table-data-gateway-vs-extending-zend-db-table-abstract\">\u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u0435 \u043c\u043d\u0435\u043d\u0438\u0435<\/a><\/p>\n<p>  \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0447\u0442\u043e \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 \u043a\u043e\u0434\u0430 \u0431\u044b\u043b\u0430 \u043f\u043e\u043b\u0435\u0437\u043d\u0430 \u0432\u0430\u043c. <br \/>  \u0422\u0430\u043a\u0436\u0435 \u0431\u0443\u0434\u0443 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u0435\u043d \u0437\u0430 \u043a\u0440\u0438\u0442\u0438\u043a\u0443, \u0441\u043e\u0432\u0435\u0442\u044b \u0438 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u043d\u043e\u0441\u0442\u0438. <\/p>\n<h6>PS <\/h6>\n<p>  \u041f\u043e\u043d\u0438\u043c\u0430\u044e, \u0447\u0442\u043e \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0435 \u0431\u044b\u0432\u0430\u0435\u0442 \u0438, \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0441\u0435\u0433\u0434\u0430, \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043b\u0443\u0447\u0448\u0435. <br \/>  \u0422\u0430\u043a\u0436\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u044e, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f. <br \/>  \u0418 \u0434\u0430, \u044f \u043f\u043e\u043d\u0438\u043c\u0430\u044e, \u0447\u0442\u043e \u0435\u0441\u0442\u044c ZF2, \u0438 \u043b\u0443\u0447\u0448\u0435 \u043d\u043e\u0432\u044b\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0430 \u043d\u0435\u043c. <br \/>  \u0422\u0430\u043a\u0436\u0435 \u044f \u043e\u0441\u043e\u0437\u043d\u0430\u044e, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438 \/ \u044f\u0437\u044b\u043a\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0449\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \/ \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \/ \u0432\u044b\u0448\u0435 \/ \u0441\u0438\u043b\u044c\u043d\u0435\u0435 \/ \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u043a\u0440\u0430\u0441\u0438\u0432\u0435\u0435 \u0438 \u0442\u043f.    \t \t\t   \t<\/p>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/169537\/\"> http:\/\/habrahabr.ru\/post\/169537\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">   \t\u041d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u043d\u0430\u0432\u0435\u044f\u043d\u043e <a href=\"http:\/\/habrahabr.ru\/qa\/34735\/\">habrahabr.ru\/qa\/34735\/<\/a> \u0438 <a href=\"http:\/\/habrahabr.ru\/qa\/32135\/\">habrahabr.ru\/qa\/32135\/<\/a> \u0432\u043e\u043f\u0440\u043e\u0441\u0430\u043c\u0438, \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0441\u043c\u043e\u0433 \u043d\u0430\u0439\u0442\u0438 \u043f\u043e\u043b\u043d\u043e\u0439 \u0438 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438, \u0447\u0435\u0433\u043e \u043e\u0447\u0435\u043d\u044c \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u043b\u043e. \u042f \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u0447\u0442\u043e \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u0430 \u0438 \u0434\u0440\u0443\u0433\u0438\u043c. <\/p>\n<p>  \u041f\u0440\u043e\u0435\u043a\u0442, \u043d\u0430 \u0447\u044c\u044e \u0434\u043e\u043b\u044e \u043f\u0430\u043b \u0432\u044b\u0431\u043e\u0440 \u0432 \u0432\u0438\u0434\u0435 ZF \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u043b \u0438\u0437 \u0441\u0435\u0431\u044f \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 (\u0430\u0434\u0430\u043f\u0442\u0438\u0432\u043d\u044b\u0439 \u0434\u0438\u0437\u0430\u0439\u043d \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043d\u044c\u044e\u0430\u043d\u0441\u0430\u043c\u0438) + \u0410\u041f\u0418 \u0434\u043b\u044f \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. <br \/>  \u041a\u043e\u043b\u043b\u0435\u0433\u0438\u0430\u043b\u044c\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u043e-\u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0434\u0438\u043d\u043e\u0435 \u0410\u041f\u0418, \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0449\u0430\u0442\u044c\u0441\u044f \u0438 \u0441\u0430\u0439\u0442, \u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. <\/p>\n<p>  \u041d\u0430 \u044d\u0442\u043e\u043c, \u0434\u0443\u043c\u0430\u044e, \u043f\u0440\u0435\u043b\u044e\u0434\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u044c \u0438 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0441\u0430\u043c\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u043c\u0443.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-169537","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/169537","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=169537"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/169537\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=169537"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=169537"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=169537"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}