What is php-fig? Entity "framework" for PHP from one class How did you get into PHP Core Team, what the way went to this

16.09.2016

Let us try to determine how you can enhance the performance of the application server on the PHP-FPM database, as well as form a check list to check the FPM process configuration.

First of all, it is worth determining the location of the pool configuration file. If you installed PHP-FPM from the system repository, then the pool configuration www. It will be located approximately here /etc/php5/fpm/pool.d/www.conf. If your build is used or another OS (not Debian), you should search the location of the file in the documentation, or specify it manually.

Let's try to consider the configuration more details.

Go to unix sockets

Probably the first thing to pay attention to is how data from a web server to your PHP processes. This is reflected in LISTEN directive:

listen \u003d 127.0.0.1:9000

If the address is set: the port is set through the TCP stack, and this is probably not very good. If there is a path to the socket, for example:

listen \u003d /var/run/php5-fpm.sock

the data go through a UNIX socket, and you can skip this section.

Why is it still worth moving on Unix socket? UDS (UNIX Domain Socket), in contrast to a communice through the TCP stack, have significant advantages:

  • do not require context switching, UDS use Netisr)
  • uDS datagram recorded directly to the destination socket
  • sending datagram UDS requires less operations (no checksums, no TCP-Capaging, not to produce routing)

TCP Average Delay: 6 US UDS Average Delay: 2 US Pipe Average Delay: 2 US TCP Average bandwidth: 253702 MSG / S UDS Average bandwidth: 1733874 MSG / S Pipe average throughput: 1682796 MSG / S

Thus, the UDS delay ~ 66% less and bandwidth in 7 times more TCP. Therefore, most likely it is worth moving on UDS. In my case, the socket will be located at /Var/Run/PHP5-FPM.SOCK.

; Comvent this - listen \u003d 127.0.0.1:9000 listen \u003d /var/run/php5-fpm.sock

You should also make sure that the web server (or any other process that communication needs) has read / write access to your socket. There are settings for this. listen.grup. and listen.mode. The easiest way is to run both processes from one user or group, in our case PHP-FPM and the web server will be launched with a group. wWW-DATA.:

listen.owner \u003d www-data listen.group \u003d www-data listen.mode \u003d 0660

Check the selected event processing mechanism

To work with efficient operation with I / O (input-output, file handlers / devices / sockets) It is worth checking whether the setting is correctly indicated. events.Mechanism. If PHP-FPM is set from the system repository, most likely everything is in order there - it is either not specified (automatically installed) or specified correctly.

Its value depends on the OS, for which there is a hint in the documentation:

; - Epoll (Linux\u003e \u003d 2.5.44); - KQueue (FreeBSD\u003e \u003d 4.1, OpenBSD\u003e \u003d 2.9, NetBSD\u003e \u003d 2.0); - / Dev / Poll (Solaris\u003e \u003d 7); - Port (Solaris\u003e \u003d 10)

For example, if we work on a modern Linux distribution we need Epool:

events.Mechanism \u003d Epoll

Pool type selection - DYNAMIC / STATIC / Ondemand

Also, it is worth paying attention to the process manager settings (PM). In essence, this is the main process (Master Process), which will manage all the subsidiaries (which execute the application code) by a specific logic that is actually described in the configuration file.

In total, 3 process management schemes are available:

  • dynamic
  • static.
  • ondemand.

The simplest is static.. The scheme of its work is as follows: run a fixed number of child processes, and maintain them in working condition. This operation scheme is not very effective, since the number of requests and their load may vary from time to time, and the number of child processes are not - they always occupy a certain amount of RAM and cannot process peak loads in the order of queue.

dynamic The pool will solve this problem, it adjusts the number of child processes based on the values \u200b\u200bof the configuration file, changing them into a large or smaller side, depending on the load. This pool is most suitable for the application server, which requires a quick response to a request, work with peak load, resource saving is required (by reducing subsidiaries when simple).

ondemand. pool is very similar to static.But it does not launch child processes at the start of the main process. Only when the first request comes - the first child process will be created, and after the expiration of a certain waiting time (specified in the configuration) it will be destroyed. Therefore, it is relevant for servers with limited resources, or that logic that does not require a rapid response.

Memory leaks and oom killer

Attention should be paid to the quality of the applications that will be performed by child processes. If the application's quality is not very high, or multiple third-party libraries are used, then you need to think about possible memory leaks, and set values \u200b\u200bsuch a variable:

  • pm.max_requests.
  • request_Terminate_Timeout.

pm.max_requests. This is the maximum number of requests that the child process processes before being destroyed. Forced destruction of the process avoids the situation in which the memory of the child process will "swell" due to leaks (because the process continues to work after request to request). On the other hand, too small value will lead to frequent restarts, which will lead to losses in performance. It is worth starting with a value of 1000, and further reduce or increase this value.

request_Terminate_Timeout. Sets the maximum execution time of the child process before it is destroyed. This allows you to avoid long requests, if for any reason the value of max_execution_time was changed in the interpreter settings. The value is to establish based on the logic of the applications processed, say 60s. (1 minute).

Setting up Dynamic Pula.

For the main server application, due to explicit advantages, the dynamic pool often choose. Its work is described by the following settings:

  • pM.Max_Children. - Maximum number of subsidiaries
  • pm.Start_Servers. - the number of processes at the start
  • pm.min_spare_servers - Minimum number of processes waiting for connections (Requests for processing)
  • pM.Max_Spare_Servers - Maximum number of processes waiting for connections (Requests for processing)

In order to correctly establish these values, it is necessary to consider:

  • how much memory average consumes a child process
  • volume of accessible RAM

Find out the average memory value to one PHP-FPM process on an already running application using the scheduler:

# PS -YLC PHP-FPM --SORT: RSS S UID PID PPID C PRI NI RSS SZ WCHAN TTY TIME CMD S 0 1445 1 0 80 0 9552 42588 EP_POL? 00:00:00 PHP5-FPM

We need the average value in the RSS column (the size of the residence in kilobytes). In my case it is ~ 20mb. If there are no loads on the application, you can use Apache Benchmark to create the simplest load on PHP-FPM.

The total / accessible / memory required can be viewed using free.:

# Free -m Total USED FREE ... MEMORY: 4096 600 3496

Total Max Processes \u003d (Total Ram - (Used RAM + Buffer) / (Memory Per PHP Process) Total RAM: 4GB Used RAM: 1000MB Safety buffer: 400MB Memory for one child PHP-FPM process (on average): 30MB Maximum possible Number of processes \u003d (4096 - (1000 + 400)) / 30 \u003d 89 even quantity: 89 rounded to a smaller side up to 80

The value of the remaining directives can be set on the basis of the expected load on the application and also to take into account the other server other than the PHP-FPM operation (say the DBMS also requires resources). If there are many tasks on the server - it is necessary to reduce K-in as initial / maximum processes.

For example, we take into account that there are 2 pools www1 and www2 (for example 2 web resources), then the configuration of each of them may look like:

pm.max_children \u003d 40; 80/2 PM.START_SERVERS \u003d 15 PM.MIN_SPARE_SERVERS \u003d 15 PM.MAX_SPARE_SERVERS \u003d 25

PHP programming language It was a big way from the tool to create personal pages to a general purpose. Today, it is installed on millions of servers around the world, is used by millions of developers who create a lot of a variety of projects.

It is easy to study and extremely popular, especially among newcomers. Therefore, after the development of the language, the powerful development of the community around it followed. A huge number of scripts, for all occasions, different libraries, frameworks. The lack of single norms of registration and writing code, led to the emergence of a huge reservoir of information products built on their own principles of the developer of this product. This was especially noticeable when working with various Php frameworkswhich for a long time was a closed ecosystem that is not compatible with other frameworks, despite the fact that the tasks that are often solved by them are often similar.

In 2009, the developers of several frameworks agreed to create a community PHP Framework Interop Group (PHP-Fig)that would produce recommendations for developers. It is important to emphasize that it is not about ISO standards, more correctly talk about recommendations. But since creating Php-fig The community developers represent major frameworks, their recommendations are of serious weight. Support PSR (PHP Standart Recommendation) standards Allows you to ensure compatibility, which facilitates and speeds up the development of the final product.

In total, at the time of this writing, there are 17 standards, and 9 of them are approved, 8 are in the project stage, are actively discussed, 1 standard is not recommended for use.

Now let's move directly to the description of each standard. Note that I will not disassemble each standard in detail here, rather this is a slight introduction. Also in the article only those will be considered pSR standardswhich are officially accepted, i.e. are located in the status of Accepted..

PSR-1. Basic coding standard

It is the most general rules, such as, for example, the use tags php., Encoding files, separating the place of ads of the function, class and place of use, the name of classes, methods.

PSR-2. Code Style Guide

It is a continuation of the first standard and regulates the issues of use in the tab code, rows transfers, the maximum length of the lines of code, the rules for registration of control structures, etc.

PSR-3. Logging interface.

This standard is designed to provide (journaling) logging in applications written in Php..

PSR-4. Standard autoload

This is probably the most important and necessary standard to which separate, detailed article be dedicated. Classes that implement PSR-4.can be downloaded by a single autoloader, which allows parts and components from one framework or library to be used in other projects.

PSR-6. Caching interface

Caching is used to increase system performance. AND PSR-6. Allows you to store and extract data from the cache using a unified interface.

PSR-7. HTTP messaging interface

When writing a little difficult sites on PHP., almost always have to work with Http headlines. Sure, pHP language provides us with ready-made opportunities with them, such as superGlobal $ _Server arrayFunctions header (), setcookie () Etc., however, their manual analysis is fraught with errors, and it is not always possible to take into account all the nuances of working with them. And so to facilitate the work of the developer, as well as make a uniform interface of interaction with Http protocol This standard was adopted. In more detail about this standard, I will tell in one of the following articles.

PSR-11. Container interface

When writing PHP programs Often you have to use third-party components. And in order not to get lost in this dependency in this forest, various methods of code dependences were invented, often incompatible among themselves, which given standard and leads to a common denominator.

PSR-13. Hypermedia Links

This interface is designed to facilitate the development and use of application programming interfaces ( API.).

PSR-14. Simple caching interface

Is a continuation and improvement of the standard PSR-6.

Thus, today we reviewed PSR standards. For current information about the status of standards, please contact

PHP can be fully called the "web programming language", it is very difficult to find another such language that could compete with it in terms of its popularity. I decided to learn how to learn people behind his development, answer the sharp questions, discuss the latest new items, and even try to look into the future of the Internet. For this we met with legendary participants PHP Core Team.which directly oversee the development of this language and have earned a reputation as recognized world experts in the field of web technologies.

So today the leading developers from PHP Core Team. - (Andrei Zmievski), (Stas Malyshev), (Ilia Alshanetsky).

To begin with, please tell me a little about yourself - what are you doing now and where you work. Remember the story of how you came to the world of programming.

CM: Now I live in the United States and work in the firm, I am engaged in infrastructure of this product - i.e. Those parts of the system that provide a database for overall functionality and provide an interface for developing specific modules.

If we talk about the history of my arrival in programming, I started at school, with and with programs published in the journal " Technique - youth" Although at first it was impossible to be called programming - I basically simply introduced programs printed in the journal, in the memory of the car and watched what was obtained. But then I wanted myself to learn how to force this difficult (at that time) the car to do what I want, and I began to understand - on my own and with the help of the elders - how it all works. He participated in the circles, squatched the clock in the library for reading foreign magazines, wrote the programs for his pleasure, and then - and for money. It turned out that I like to force computers to benefit, and to my great luck, such a skill enjoys a good demand today in the labor market.

List everything that influenced me on this path will be difficult, but the biggest effect on me, probably, had books, in particular work, ("Mythical Man-Month") and (The Inmates Are Running the Asylum - in Russian translation "The mental hospital in the hands of patients").

AZ: For 5 years, I live in San Francisco and believe that this is the most beautiful city in America. I work in the company. Although it is a relatively young startup, we have about 110-120 employees. A variety of firms around the world use our product to monitor their business systems and to quickly find problems. We have large clients, such as Netflix, Priceline and others.

About my novel with programming ... I think that rather this profession chooses you than you. I remember when I was 9 years old, I received my first programmable calculator, but before that I had noticeable deposits for mathematics, logic, and technical things - as far as I remember, these abilities were initially.

As a bright example of how it all began, I will give a story from childhood. Then, I, like most Soviet children, was not at home my computer, so I regularly went to a computer center where you could rent an hourly car and work on Basic and Pascal. I went there several times a week, but once coming from the very early morning, I was so interested that with my head I fell into an interesting program to me, while I completely lost a sense of time and forgot that it was time to go home.

I woke up only when this center was already closed, at 10 pm. By that time, parents had already phoned all my friends, teachers, etc. In search of me, but fortunately, they stumbled upon me returning from the center. I then got very much, but looking back, I understand: how much I remember myself, I always wrote the programs and lived in this partly a virtual world, so my current profession is just a continuation of a fascinating journey started in childhood.

IA: I live and work in Toronto, Canada.

As for my arrival in programming, it is still surprising for me. At the very beginning of my path, programming was rather a hobby, except for one random work, somehow obtained by me for the summer, and the associated low-level development on C. Consciously in the younger, I never put the tasks and plans to do this professionally. Against the background of the amateur picking of their programs on the SI once, I was involved in my first custom web development, which was made in the PERL language. From here it begins my way to the Internet and my specialization in web programming.

Unfortunately, as this project grows on Perl, I still did not like the inconsistency of this language, and here "tortured" a hosting company that served me at the time, once herself suggested trying a new PHP time. I immediately liked this language, because it was better structured and closer in its syntax to my beloved si. Excellent online documentation - completed my fast and final transition to it.


Ilya Alshanetsky (Ilia Alshanetsky)

I began to use PHP 3 so actively, which gradually began to appear their own developments, expanding his capabilities that began to regularly offer its creator of Rasmus in the IRC channel. Patches and corrections from me was so much that he was quickly tired of it, and he gave me direct CVS access to the repository of the project. Since then, there have been a lot of things written and done, I even had the opportunity to be a release manager (PHP Release Master) for its popular versions of 4.3, 5.1 and 5.2.

By the way, in parallel with this activity there were a lot of consulting work for external commercial customers, for whom, in particular, sometimes very extraordinary problems with productivity, scalability and security of their own projects created on PHP were solved. In one of these consultations, I was so deeply plunged into their project, which eventually became a partner of this company (Centah Inc.) and received a CIO position in it, where I am currently working.

How did you get into PHP Core Team, what way went to this?

AZ: Let me answer on your example, but first a little history. I started working with PHP somewhere in 1998, then it was PHP 3, one of the earliest versions. We rewritten a big project from another language into PHP, and I needed to find support now almost forgotten. I did not find such a library, but I really liked that PHP had excellent documentation and API, so I decided to write my expansion. When I finished, immediately sent it to the PHP mailing. And they unexpectedly decided to add it to the next release of the tongue.

Subsequently, I was given access to CVS, and I began to repair bugs, writing more different functions, etc. By the end of 1999, I was one of the most active members of the group, and then suggested organizing the first congress of PHP developers in Israel to discuss the future of the language, and included me in this newsletter. So there was no vote, it just happened that I immediately got into PHP Core Team..


Rasmus Lerdorf (Rasmus Lerdorf), Creator PHP

Such trust and openness motivated me to work more and more over the PHP code. After WDDX, I worked on a session module, then wrote a bunch of functions for working with arrays, then I decided that PHP should have regular expressions like Perl, so created a PCRE module. By that time, PHP 4 had long come out, but I was very annoyed by some problems with how I worked (or rather did not work) objects and classes. On this occasion, I had a lot of correspondence with Andi and Zeev, which created, and from it turned out fundamentally new support Object-Oriented Programming In then the new PHP 5.

After that, I worked mainly over the code for Zend Engine himself, also made a new tokenizer module. Since 2003, along with Rasmus, and there I launched a project to support Unicode in PHP, but this is for the other times ...

What do you think is this in PHP, what made it so popular?

AZ: It so happened that at the moment I am writing a project on C ++ and Python, so I will answer on the basis of this comparative experience, looking like this "other bell tower".

For me, the main thing is that PHP has a rich and extensive API, with which you can expand the language in many, even sometimes unexpected directions. On the other hand, I often hear from people how easily it was to start using PHP and how they like that you can write a website or a program in a matter of hours. Here is the essence of PHP: it is at the same time complex and simple, old-fashioned and modern, original and borrowing ideas from the outside - it is simply very versatile.

Security-related errors are the main headache for web programmers and numerous users of their products. Looking around on your rich experience, what are the most important and typical problems with the security of PHP and its developers you can highlight? Can you give some advice in the edification of young PHP programs?

CM: One of the main lessons, it seems to me is that the safety of the code is not the quality that can be instilled outwardly, regardless of the rest of the code. Caring for safety should be the daily part of the work, from the very first minute, starting with the design and to the release of the finished product. In PHP, several attempts have been made to add the security tools "from outside" - but experience has shown that these attempts, without constant vigilance by programmer, are doomed to failure. The platform can only help him follow the security of the code, but cannot guarantee this safety without effort from its part.

Therefore, the main advice will be the following - never trust any external data, or data, control over which is possible. 99% of security issues occur because the assumptions made about the input data are incorrect, and when the attack subsequently occurs, the code does not behave as the developer himself conceived. Therefore, develop a habit of asking yourself always - "What if this parameter is to change an unexpected way? What if this argument applies not as it was assumed? " And test your code, respectively.

The next my recommendation is instead of checking "there is no problem of something unauthorized", preventively convert data so that they are guaranteed as needed. So it will be much easier to avoid mistakes. Also, do not rely that other parts of the code will take care of the safety - for example, if you make a dynamic database request, always make sure that the parameters and request are generated and filtered in such a way that sQL Injection It is impossible - even if you are sure that the data is still filtered (for example, at the framework level). Then, if the external code is changed in such a way that non-filtered data suddenly fall into your procedure, vulnerabilities will not arise anyway.

The rapid growth of mobile applications is likely to continue, but many of them will switch to HTML5 as a universal platform. In this regard, there will be a need to develop data synchronization protocols, as well as in the development of models that allow us to work simultaneously with both traditional browsers and various mobile clients who often have different features.

In general, the browser will finally become a full part of the web infrastructure, and therefore a part of the responsibilities executed by the server now will turn over the client side. Therefore, I would advise people working now with PHP, at the same time follow the latest achievements in the JavaScript, HTML5, CSS3, etc.

I thank the members PHP Core Team.who, despite the big employment, kindly found the time to answer questions for our readers.

Characters:


Andrei Zmeievsky, one of the curators PHP Project., developer Zend Engine, creator of projects and, co-author of the popular textbook, author of Unicode and OOP implementations in PHP. In his free time he is fond of sports, brewing at home, cooking. Loves a lot to read and travel.

Stas Malyshev, participant PHP Project. Since 2000, the release manager of PHP 5.4, a member of many OpenSource projects. In his free time, intellectual games (sports version "What? Where? When?", "Brain Ring") and Aikido.

Ilya Alschenetsky, Security expert and one of the oldest developers PHP, chapter, release-manager of PHP 4.3, 5.1, 5.2 versions, the creator of the forum engine, an active member of the set OpenSource projects. And on the security of web programming.

p.S.: I promise that in the new 2013 I will post more than many VIP interviews with the leading world developers, let some specifies be a secret.

1. Group by One Key

This Function Works As Group by For Array, But One Important Limitation: Only One Grouping "COLUMN" ($ Identifier) \u200b\u200bis possible.

Function ArrayUniQuebyidentifier (Array $ Array, String $ Identifier) \u200b\u200b($ IDS \u003d Array_Column ($ Array, $ Identifier); $ IDS \u003d Array_unique ($ IDS); $ Array \u003d Array_Filter ($ Array, Function ($ Key, $ Value) Use ($ IDS) (RETURN IN_ARRAY ($ VALUE, Array_Keys ($ IDS));), array_filter_use_both); return $ array;)

2. Detecting The Unique Rows For a Table (Twodimensional Array)

This Function Is For Filtering "Rows". If We Say, A TWODIMENSIONAL ARRAY IS A TABLE, THEN ITS EACH ELEMENT IS A ROW. SO, We Can Remove The Duplicated Rows with This Function. Two Rows (Elements of the first dimension) Are Equal, IF All Their Columns (Elements of the Second Dimension) Are Equal. To the Compassion of "Column" Values \u200b\u200bApplies: If a Value Is of a Simple Type, The Value Itself Will Be Use On Comparing;: IF A VALUE ITSELF WILL BE USE ON COMPARING; OtherWise ITS Type (Array, Object, Resource, Unknown Type) Will Be used.

The Strategy IS Simple: make from the original Array A SHALLOD ARRAY, WHERE THE ELEMENTS ARE IMPLODE D "COLUMNS" OF THE ORIGINAL ARRAY; Then Apply Array_unique (...) on It; And AS Last Use the Detected IDS for Filtering Of The Original Array.

Function ArrayUniqueByrow (Array $ Table \u003d, String $ ImplodeSeparator) ($ elementstrings \u003d; foreach ($ table as $ row) (// to avoid notices like "Array to String Conversion". $ ElementPreparedForImPlode \u003d Array_Map (Function ($ Field) ( $ Valuetype \u003d GetType ($ Field); $ SimpleTypes \u003d ["Boolean", "Integer", "Double", "Float", "String", "NULL"]; $ field \u003d in_array ($ Valuetype, $ SimpleTypes)? $ field: $ valueType; return $ field;), $ row); $ elementStrings \u003d implode ($ implodeSeparator, $ elementPreparedForImplode);) $ elementStringsUnique \u003d array_unique ($ elementStrings); $ table \u003d array_intersect_key ($ table, $ elementStringsUnique); Return $ Table;)

IT "S ALSO POSSIBLE TO IMPROVE THE COMPARING, DETETING THE" COLUMN "VALUE" S CLASS, IF its Type is Object.

The $ ImplodeSeparator Should Be More or Less Complex, Z.B. SPL_Object_Hash ($ this).

3. Detecting the Rows with Unique Identifier Columns For a Table (Twodimensional Array)

This Solution Relies on the 2nd One. NOW THE COMPLETE "ROW" DOESN "T Need to Be Unique. Two" Rows "(Elements of the first dimension) Are Equal Now, if All rELEVANT. "Fields of the One" Row "Are Equal To the According" Fields "(Elements with the Same Key).

The "Relevant" "Fields" Are The Second Dimension "(Elements of the Second Dimension), Which Have Key, That Equals to One of the Elements of the Passed" Identifiers ".

Function arrayUniqueByMultipleIdentifiers (array $ table, array $ identifiers, string $ implodeSeparator \u003d null) ($ arrayForMakingUniqueByRow \u003d $ removeArrayColumns ($ table, $ identifiers, true); $ arrayUniqueByRow \u003d $ arrayUniqueByRow ($ arrayForMakingUniqueByRow, $ implodeSeparator); $ arrayUniqueByMultipleIdentifiers \u003d array_intersect_key ($ table, $ arrayuniquebyRow); Return $;) Function RemoveArrayColumns (Array $ Table, Array $ Columnnames, BOOL $ iSwhitelist \u003d False) (foreach ($ table as $ rowkey \u003d\u003e $ ROW) (IF (IS_Array ($ ROW )) (Foreach ($ Row AS $ fieldname \u003d\u003e $ fieldValue) (if (! IN_ARRAY ($ FIELDNAME, $ columnnames)) (Unset ($ table [$ rowkey] [$ fieldname]);) )) ELSE (foreach ($ row as $ fieldname \u003d\u003e $ fieldvalue) (if (in_array ($ fieldname, $ columnnames)) (Unset ($ Table [$ Rowkey] [$ fieldname]);))))) Return $ Table;)

Since the development of technologies led to the fact that each programmer now has its own computer, as a side effect, we have thousands of various libraries, frameworks, services, APIs, etc. for all occasions. But when this case of life comes, the problem arises - what to use them and what to do if it is not quite suitable - to rewrite, write from scratch or fastening several solutions for different use options.

I think, many have noticed that it is often necessary to create a project not so much to programming how much to write code for the integration of several ready-made solutions. Sometimes such combinations turn into new solutions that can be repeatedly used in subsequent tasks.

We turn to a specific "running" task - object layer for working with databases in PHP. The solutions are a great set, ranging from PDO and ending with multi-level (and, in my opinion, not quite relevant in PHP) ORM engines.

Most of these solutions moved to PHP from other platforms. But often the authors do not take into account the features of PHP, which would allow sharply simplify both spelling and the use of portable structures.
One of the common architectures for this task class is the Active Record pattern. In particular, the so-called Entity (entity) are built on this pattern, in one form or another used in a number of platforms, ranging from persistant bins in EJB3 ending with EF VET.

So, we construct a similar design for PHP. Connect the two cool pieces to each other - the ready-made Adodb library and the lighterness and dynamic properties of the PHP objects.
One of the numerous adodb features is the so-called SQL auto-generation requests for insert (INSERT) and updates (UPDATE) records based on associative arrays with data.
Actually, there is nothing military to take an array where the keys are the names of the fields and the values \u200b\u200b- respectively, the data and generate the SQL promptee string. But ADODB does it more intellectually. The request is based on a table structure, which is previously read from the database scheme. As a result, first, only existing fields are falling in SQL, and not everything, secondly, the field type is taken into account - quotes are added for strings, dates can be formed on the basis of timestamp if ADODB sees it instead of a string in the transmitted value, etc. .

Now go from PHP.
Imagine such a class (simplified).

Class Entity (Protected $ Fields \u003d Array (); Public Final Function __set ($ Name, $ Value) ($ this-\u003e fields [$ name] \u003d $ value;) Public Final Function __Get ($ Name) (RETURN $ THIS- \u003e Fields [$ Name];))

By passing an internal array of the ADODB library, we can automatically generate SQL requests to update the entry in the database with this object, while not needed bulky designs of the Mapping fields of the database tables on the Entility Object Field based on XML and the like. It is only necessary that the field name coincides with the object property. Since how fields are referred to in the database and object fields, the value does not have a value for the computer, then there is no reason that they do not coincide.

Show how it works in the final version.
The code of the completed class is located on Gist. This is an abstract class containing the minimum necessary to work with the database. I note that this class is a simplified version of the solution spent on several dozen projects.

Imagine that we have such a sign:

Create Table `Users` (` username` Varchar (255), `Created` Date,` user_id` Int (11) Not Null AUTO_INCREMENT, PRIMARY KEY (`user_id`))
The database type does not matter - ADODB provides portability for all common database servers.

Create a class of entity user, based on the Entity class

/ ** * @ Table \u003d Users * @ Keyfield \u003d User_ID * / class User Extends Entity ()

Actually, all.
Used simply:

$ User \u003d NEW User (); $ User-\u003e Username \u003d "Vasya Pupkin"; $ User-\u003e Created \u003d Time (); $ User-\u003e Save (); // Save to the repository // Upload again $ ThesameUser \u003d User :: Load ($ User-\u003e User_ID); Echo $ ThesameUser -\u003e UserName;

Table and key field indicate pseudoannotation.
We can also specify the presentation (for example, view \u003d usersview) If, as it often happens, the entity is selected based on its table with southerners or calculated fields. In this case, the data will be selected from the view, and the table will be updated. Who do not like such annotations can override the getmetatada () method and specify the table parameters in the returned array.

What else uses the Entity class in this implementation?

For example, we can override the init () method, which is called after creating an Entity instance to initialize the default creation date.
Or overload the Afterload () method, which is automatically called after loading the entity from the database to convert the date in TimeStamp for further more convenient use.
As a result, we get a much more complex design.

/ ** * @ Table \u003d Users * @ View \u003d UsersView * @ keyfield \u003d user_id * / class user EXTENDS ENTITY (PROTECTED FUNCTION INIT () ($ THIS-\u003e CREATED \u003d TIME ();) PROTECTED FUNCTION Afterload () ($ this -\u003e Created \u003d Strtotime ($ this-\u003e created);))

You can also overload BEForesave and BeforeElete methods and other life cycle events where you can, for example, perform validation before saving or some other actions - for example, remove pictures from an appleader when deleting a user.

We download the list of entities by the criterion (essentially the condition for where).
$ Users \u003d User :: Load ("UserName Like" Pupkin ");
Also, the Entity class allows you to perform arbitrary, "native" so to speak SQL query. For example, we want to return a list of users with some static groups. What the specifically the fields will return, it does not matter (the main thing is to be user_id, if there is a need for further manipulation of the entity), you just need to know their names to turn to the selected fields. When the entity is maintained, as apparently from the above, it is also not necessary to fill in all fields that will be present in the object of entity, those will go to the database. That is, we do not need to create additional classes for arbitrary samples. Approximately as an anonymous structures when sampling in EF, only here is the same class of entity with all business logic methods.

Strictly speaking, the above methods for obtaining lists go beyond the limits of the Ar Pattern. In essence, these are factory methods. But how the old man of Okkam bequeathed, we will not produce the essences in the excess of the necessary and burning a separate Entity Manager or type of one.

Note that the above is simply the PHP classes and they can be accessed and modified, adding in essence (or the basic Entity class) properties and methods of business logic. That is, we do not just get a copy of the database table rows, namely a business entity as part of the object architecture.

Who can it be useful? Of course, not pumped irregularities, which believe that the use of something is easier the doctrine is not solid, and not perfectionists, confident that if the decision does not pull a billion appeals to the database within a second, this is not a solution. Judging by the forums, in front of many conventional developers working on ordinary (koi 99.9%) projects sooner or later there is a problem to find a simple and convenient object method for access to the database. But faced with the fact that most of the solutions are either unjustified, or are part of any framework.

P.S. Ruled out of the framework a separate project

Did you like the article? To share with friends: