Ohwow user info PHP. Global $ _Server array in PHP. What functionality we will support

SuperGlobal $ _Server array

One of the most important predefined arrays is an $ _Server array - a PHP interpreter places variables received from the server. Without these variables, it is difficult to organize full support for Web applications. The following is a description of the most important elements of the superglobal array $ _Server.

Comment

View a complete list of an array of $ _Server array can be either using the print_r () function, which prints the dump of the array or using the PHPInfo () function, which displays information about the PHP interpreter.

Element $ _Server ["document_root"]

The $ _Server element ["document_root"] contains the path to the server's root directory if the script is performed in the virtual host, this element indicates the path to the root directory of the virtual host. Those. In the configuration file httpd.conf, the virtual host has a DocumentRoot directive, which is assigned the value "D: / MAIN", the $ _Server element ["Document_Root"] will contain the value "D: MAIN".

Element $ _Server ["http_accept"]

The $ _Server element ["http_accept"] describes the client preferences relative to the type of document. The contents of this element is removed from the HTTP header of the Accept, which sends the client to the server. The contents of this title may look as follows.

image / Gif, Image / X-XBitmap, Image / Jpeg, Image / Pjpeg, Application / X-Shockwave-Flash, Application / VND.MS-Excel, Application / MSWORD, * / *

The ACCEPT header allows you to clarify the media type that prefers to get the client in response to your request. This title allows you to tell the server that the answer is limited by a small set of preferred types.

The * symbol is used to group types in the media row. For example, the * / * symbol is set to use all types, and the Type / * designation determines the use of all subtypes of the selected type type.

Comment

Media types are separated from each other commas.

Each media series is also characterized by an additional set of parameters. One of these is the so-called relative preference coefficient Q, which takes values \u200b\u200bfrom 0 to 1, respectively, from less preferred types to more preferred. The use of several parameters Q allows the client to inform the server with a relative degree of preference for a particular media type.

Comment

By default, the parameter q takes a value 1. In addition, from the media-type it is separated by a semicolon.

An example of a header type Accept:

ACCEPT: Audio / *; Q \u003d 0.2, Audio / Basic

In this title, the first type AUDIO / * includes all the music documents and characterized by the preference ratio of 0.2. Through the comma, the type of Audio / Basic is specified, for which the preference coefficient is not specified and the default value is equal to one. By quoting RFS2616 This title can be interpreted as follows: "I prefer the type of Audio / Basic, but I can also send documents of any other Audio-type if they are available, after reducing the preference coefficient by more than 80%."

An example may be more complicated.

Accept: Text / Plain; q \u003d 0.5, Text / HTML,
Text / X-DVI; Q \u003d 0.8, Text / X-C

Comment

It should be borne in mind that the $ _Server [HTTP_ACCEPT] element contains exactly the same information, but without the initial accept header.

This header is interpreted as follows: Types of Text / HTML and Text / XC documents are preferred, but if they are not available, then the client sending this request will prefer the text / x-dvi, and if it is not, then it can take Type Text / Plain.

Element $ _Server ["http_accept_language"]

The $ _Server element ["http_accept_language"] describes the client preferences relative to the language. This information is extracted from the ACCEPT-Language HTTP header, which sends the client to the server. You can give the following example:

Accept-Language: RU, EN; Q \u003d 0.7.

Which can be interpreted as follows: the client prefers Russian, but in the case of its absence I agree to accept documents in English. An element $ _Server ["http_accept_language"] will contain exactly the same information, but without the ACCEPT-Language header:

rU, EN; Q \u003d 0.7.

The contents of the $ _Server element ["http_accept_language"] can be used to determine the national affiliation of visitors. However, the results will be approximate because many users use English browser versions that will notify the server that the visitor prefers only one language - English.

Element $ _Server ["http_host"]

The $ _Server element ["http_host"] contains a server name, which, as a rule, coincides with the domain name of the site located on the server. As a rule, the name specified in this parameter coincides with the name $ _Server ["Server_Name"]. The parameter provides only a domain name without the protocol name (http: //), i.e.

www.sofftime.ru.

Element $ _Server ["http_referer"]

The $ _Server element ["http_referer"] is given a page address with which the visitor came to this page. The transition must be exercised by reference. Create two index.php and page.php pages.

Page index.php.

echo. "Link to PHP page
"
;
Echo.
$ _Server ["http_referer"]
?>

Page.php page will be similar content, but the link will indicate the index.php page.

Page. Page.php.

echo. "Link to PHP page
"
;
Echo. "CONTENT $ _SERVER [" http_referer "] -".
$ _Server ["http_referer"]
?>

When you go from one page to another, the address of the page will be displayed with which the transition was carried out.

Element $ _Server ["http_user_agent"]

The $ _Server ["http_user_agent"] element contains information about the type and version of the browser and the visitor operating system.

Here is the typical content of this string: "Mozilla / 4.0 (compatible; MSIE 6.0; Windows NT 5.1)". The presence of a substring "MSIE 6.0" suggests that the visitor browsing the page using Internet Explorer version 6.0. The "Windows NT 5.1" row reports that Windows XP is used as the operating system.

Comment

For Windows 2000, the $ _SERVER ["http_user_agent"] element looks like this: "Mozilla / 4.0 (compatible; MSIE 5.01; Windows NT 5.0)") ", while for Windows XP -" Mozilla / 4.0 (compatible; MSIE 6.0 ; Windows NT 5.1) ".

If the visitor comes with the Opera browser, then the content of $ _Server ["http_user_agent"] may look like this: "Mozilla / 4.0 (compatible; MSIE 5.0; Windows 98) Opera 6.04". MSIE 6.0 substring here is also present, reporting that the Opera browser is compatible with the Internet Explorer browser and uses the same Windows dynamic libraries. Therefore, when analyzing a row returned by the browser, it should be borne in mind that the Internet Explorer includes a string containing the MSIE 6.0 substitute and does not contain the "Opera" substring. In addition, from this line, it can be concluded that the user uses the Windows 98 operating system.

Comment

The Firefox browser user agent may look as follows Mozilla / 5.0 (Windows; U; Windows NT 5.1; EN-US; RV: 1.8) GECKO / 20051111 Firefox / 1.5.

When using the NetScape browser, the content of the $ _Server ["http_user_agent"] element may look as follows: "Mozilla / 5.0 (x11; U; Linux i686; EN-US; RV: 1.4) GECKO / 20030624 NETSCAPE / 7.1". Belonging to this browser can be determined by the presence of a substring "NetScape". In addition, you can find out that the visitor goes into the Internet using the operating version of Linux, with a kernel optimized for Pentium IV, while in the X-Window graphics shell. This mechanism is convenient to use to collect statistical information, which allows designers to optimize pages for the most common browsers.

Element $ _Server ["Remote_ADDR"]

The IP address of the client is placed in the $ _Server ["Remote_ADDR"] element. When testing on a local machine - this address will be equal to 127.0.0.1. However, when testing on the network, the variable will return the client's IP address or the last proxy server through which the client hit the server. If the client uses the proxy server to learn its IP address using the HTTP_X_Forwarded_For environment variable, the value of which can be obtained using the GETENV () function.

Comment

Proxy servers are special intermediate servers providing a special type of service: compression of traffic, data encoding, adaptation under mobile devices, etc. Among the multiple proxy servers distinguish the so-called anonymous proxy servers that allow you to hide the true IP address of the client, such servers do not return the HTTP_X_Forwarded_FOR environment variable.

Removing the HTTP_X_Forwarded_For environment variable

eCHO GETENV (http_x_forwarded_for);
?>

Element $ _Server ["script_filename"]

The $ _Server element ["script_filename"] is placed an absolute path to the file from the root of the disk. So, if the server runs running the Windows operating system, then this path may look like this "D: Main Estindex.php", i.e. The path is specified from the disk, in a UNIX-like operating system, the path is indicated from the root directory /, for example, "/Var/Share/www/Test/index.php".

Element $ _Server ["Server_Name"]

In the $ _Server ["Server_name"] element, the server name is placed, as a rule, coinciding with the domain name of the site located on it. For example,

www.softtime.ru.

The contents of the $ _Server element ["Server_name"] often coincides with the content of the $ _Server element ["http_host"]. In addition to the server name, the superglobal array of $ _Server allows you to find out another number of server parameters, such as the IP address of the server, listening to the port, which WEB server is installed and the version of the HTTP protocol. This information is placed in the $ _Server ["Server_addr"], $ _Server ["Server_Port"], $ _Server ["Server_Software"] and $ _Server ["Server_protocol"], respectively. The following is an example using data items.

Using an array elements $ _Server

echo "Server Name -". $ _Server ["Server_Name"]. "
" ;
Echo. "Server IP address". $ _Server ["Server_addr"]. "
" ;
Echo "Port Server -". $ _Server ["Server_PORT"]. "
" ;
Echo "Web server -". $ _SERVER ["Server_Software"]. "
" ;
Echo. "HTTP protocol version -". $ _Server ["Server_protocol"]. "
" ;
?>

Element $ _Server ["Request_Method"]

The $ _Server [Request_Method] element is placed in the query method, which is used to call the script: Get or Post.

Possible attacks

Using PHP as a binary CGI application is one of the options when for some reason unwanted to integrate PHP to a web server (for example Apache) as a module, or it is supposed to use such utilities as Chroot and Setuid to organize a safe environment during operation. scripts. This installation is usually accompanied by copying the PHP executable file to the CGI-BIN directory of the web server. CERT (Organization following security threats) CA-96.11 recommends not to place any interpreters in the CGI-BIN directory. Even if PHP is used as an independent interpreter, it is designed to prevent the possibility of the following attacks:

    Access to system files: http://my.host/cgi-bin/php?/etc/passwd

    The data entered in the query line (URL) after the question mark is transmitted to the interpreter as the command line arguments according to the CGI protocol. Usually interpreters open and execute the file specified as the first argument.

    In the case of using PHP through the CGI protocol, it will not interpret the arguments of the command line.

    Access to an arbitrary document on the server: http://my.host/cgi-bin/php/secret/doc.html

    According to the generally accepted agreement, part of the path in the requested page, which is located after the name of the PHP module performed, /secret/doc.html, is used to specify a file that will be interpreted as a CGI program usually, some configuration options for a web server (for example, Action for server Apache) are used to redirect the document, for example, to redirect the requests of the type http://my.host/secret/script.php interpreter PHP. In this case, the web server first checks the access rights to the / Secret directory, and then creates a redirected request http://my.host/cgi-bin/php/secret/script.php. Unfortunately, if the request is initially set in full form, checking for the /secret/script.php file is not performed, it occurs only for the file / CGI-BIN / PHP. Thus, the user has the ability to refer to / CGI-BIN / PHP, and, as a result, to any secure document on the server.

    In PHP, pointing at the compilation option --Enable-Force-CGI-Redirect, And so the options doc_root and user_dir during the script, you can prevent similar attacks for directory with limited access. More detailed options, as well as their combinations will be discussed below.

Option 1: Only publicly available files are serviced.

If there are no files on your server, access to which is limited by password or filter by IP addresses, there is no need to use these options. If your web server does not allow redirects or does not have the ability to interact with the executable PHP module at the required security level, you can use the option --Enable-Force-CGI-Redirect During the assembly of PHP. But at the same time, you must make sure that alternative ways of calling the script, such as directly calling http://my.host/cgi-bin/php/dir/script.php or with forwarding http://my.host/dir/script .php, unavailable.

In the Apache web server, redirection can be configured using the AddHandler and Action directives (described below).

Option 2: Use --Enable-Force-CGI-REDIRCT

This option, specified during the PHP assembly, prevents the scripts to be called directly at the address of the http://my.host/cgi-bin/php/secretdir/script.php. Instead, PHP will handle the requested request only if it is redirected by a web server.

Usually, redirection in the Apache web server is configured using the following options:

Action PHP-Script / CGI-BIN / PHP AddHandler PHP-script .php

This option is verified only for the Apache web server, its operation is based on the installation in case of redirection of the non-standard variable Redirect_status, located in the CGI environment. If your web server does not provide the ability to unambiguously identify whether this request is redirected, you cannot use the option described in this section and should use any other method of working with CGI applications.

Option 3: Using Doc_ROoot and User_Dir options

Placing dynamic content, such as scripts or any other executable files, in the web server directory makes it potentially dangerous. If an error is made in the server configuration, a situation is possible when scripts are not performed, but are displayed in the browser, as ordinary HTML documents, which can lead to leakage of confidential information (for example, passwords), or information that is intellectual property. Based on such considerations, many system administrators prefer to use a separate directory to store scripts, working with all files placed in it by the CGI interface.

If it is impossible to ensure that requests are not redirected, as shown in the previous section, you must specify the Doc_ROoot variable, which differs from the root directory of web documents.

You can set the root directory for PHP scripts by setting up the doc_root parameter in the configuration file, or by setting the environment variable PHP_Document_ROoot. If PHP is used by CGI, the full path to the open file will be built based on the value of the Doc_ROoot variable and the path specified in the query. Thus, you can be sure that the scripts will only be executed within the directory you specified (except for the user_dir directory, which is described below).

Another used when setting up security option - user_dir. In the event that the user_dir variable is not installed, the path to the open file is built relative to Doc_ROot. Request http://my.host/~user/doc.php leads to the execution of a script that is not in the home directory of the corresponding user, and the ~ user / doc.php script in the doc_root subdirectory (yes, the name of the directory begins with the symbol ~ ).

But if the Public_PHP variable is assigned a value, for example, http://my.host/~user/doc.php, then the example of the example will be executed a Doc.php script located in the user's home directory in the Public_PHP directory. For example, if the home directory of user / home / user, the /Home/user/public_php/doc.php file will be executed.

The User_DIR option is set independently of the Doc_ROoot installation, so you can control the root directory of the web server and custom directory independently from each other.

Option 4: PHP outside the Web Document Tree

One way to significantly improve the security level is to place the PHP executable module outside the web document tree, for example, in USR / Local / Bin. The only disadvantage of this approach is that the first line of each script should be:

#! / USR / Local / Bin / PHP

You must also make all the scripts executable files. Thus, the script will be considered as well as any other CGI application written in Perl, SH or any other scripted language that uses adding #! To the start of the file to start yourself.

What would be inside the script you can get the correct values \u200b\u200bof the variables by Path_info and path_translated, PHP must be configured with the option --Enable-Discard-Path.



<<< Назад Content Forward \u003e\u003e\u003e
There are still questions or something incomprehensible - welcome to our

february 5. , 2017

I do not know a single php framework. It is sad and ashamed, but the law is not yet prohibited. And at the same time play yourself with the REST API you want. The problem is that PHP by default supports only $ _Get and $ _post. And for the RESTFUL service, it is necessary to work as soon as possible with Put, Delete and Patch. And not very obvious how to culturally process many types of types Get http://site.ru/users, delete http://site.ru/goods/5 And other dimensional. How to wrap all such requests to a single point, universally disassemble them into parts and run the desired code for data processing?

Almost any php framework can do it out of the box. For example, Laravel, where routing is implemented and easy. But what if we do not need to study right now to study a new big topic, but I just want to quickly make a project with the support of the REST API? This will be discussed in the article.

What should be able to know our restful service?

1. Support all 5 main types of queries: Get, Post, Put, Patch, Delete.
2. Develop a variety of routes of the species
POST / GOODS.
PUT / GOODS / (GoodID)
Get / Users / (UserID) / Info
And other times long chains.

ATTENTION: This article is not about the basics of the REST API
I guess you are already familiar with the REST approach and understand how it works. If not, then in the Internet there are many wonderful articles on the basics of the REST - I do not want to duplicate them, my idea is to show how to work with the REST in practice.

What functionality will we support?

Consider 2 entities - goods and users.

For goods, the following is the following:

  • 1. Get / Goods / (GOODID) - Getting information about the product
  • 2. POST / GOODS. - Adding a new product
  • 3. PUT / GOODS / (GoodID) - Editing goods
  • 4. Patch / Goods / (GoodID) - Editing some parameters of goods
  • 5. DELETE / GOODS / (GoodID) - Removal of goods

By users for diversity Consider several options with Get

  • 1. Get / Users / (UserID) - full information about the user
  • 2. Get / Users / (UserID) / Info - Only general information about the user
  • 3. Get / Users / (UserID) / Orders - List of user orders

How does it work on a native PHP?

The first thing we will do is set up.htaccess so that all requests are redirected to the index.php file. It is he who will be engaged in extracting data.

The second one - we will define what data we need and write the code to receive them - in index.php.
We are interested in 3 data types:

  • 1. Request Method (GET, POST, PUT, PATCH or DELETE)
  • 2. Data from URL-A, for example, Users / (UserID) / Info - All 3 parameters are needed.
  • 3. Data from the bodies of the request
And the third, we will write a code that runs the necessary functions. Functions are divided by files, all along the fan, add new paths and methods for the RESTFUL service will be very simple.

.htaccess.

Create a file in the root of the project.htaccess

RewriteEngine on RewriteCond% (Request_FileName)! -F Rewriterule ^ (. +) $ Index.php? Q \u003d $ 1

We command these mysterious lines to do this:
1 - send all requests for any kind of king file index.php
2 - Make a string in the URL available in index.php in the GET parameter Q. That is, data from the URL / Users / (UserID) / Info We will get out of $ _get [q "].

index.php.

Consider index.php string per line. To begin with, we get the request method.

// Determine the method of request $ Method \u003d $ _Server ["Request_Method"];

Then the data from the bodies of the request

// Receive data from the body of the request $ FormData \u003d GetFormData ($ Method);

For Get and Post it is easy to pull out data from the corresponding arrays $ _Get and $ _Post. But for the rest of the methods you need to pervert slightly. Code for them is pulled out of the stream php: // inputThe code is easy to google, I just wrote a common wrap - the GETFORMDATA function ($ Method)

// Getting data from the Function GetFormData Query Body ($ Method) (// GET or POST: Data Return As IF ($ Method \u003d\u003d\u003d "Get") RETURN $ _GET; if ($ Method \u003d\u003d\u003d "POST") Return $ _post; // Put, Patch or Delete $ Data \u003d Array (); $ Exploded \u003d Explode ("&", file_get_contents ("php: // input")); foreach ($ Exploded AS $ Pair) ($ Item \u003d Explode ("\u003d", $ pair); if (Count ($ item) \u003d\u003d 2) ($ data \u003d urldecode ($ item);)) Return $ Data;)

That is, we got the necessary data, scarce all the details in GetFormData - and fine. Go to the most interesting - routing.

// Disassemble the URL $ URL \u003d (ISset ($ _ get ["Q"]))? $ _GET ["Q"]: ""; $ URL \u003d RTRIM ($ URL, "/"); $ URLS \u003d Explode ("/", $ URL);

Above, we learned that.htaccess will put the parameters from the URL-A in the Q-parameter of the $ _GET array. That is, in $ _Get ["Q"], approximately such a line will fall: users / 10.. Regardless of how the method we give the request.

BUT explode ("/", $ URL) Converts us this string into an array with which you can already work. Thus, make up any long query chains, for example,
Get / Goods / Page / 2 / Limit / 10 / Sort / Price_Asc
And be sure to get an array

$ URLS \u003d Array ("Goods", "Page", "2", "Limit", "10", "sort", "price_asc");

Now we have all the data, you need to do something useful with them. And this will make it just 4 lines of code

// Determine the router and URL Data $ Router \u003d $ URLs; $ urldata \u003d array_slice ($ URLS, 1); // Connect the router file and run the main function include_once "routers /". $ Router. ".php"; Route ($ Method, $ Urldata, $ FormData);

Catch? We start the Routers folder into which we fold the files that manipulate one entity: goods or users. At the same time, we agree that the name of the files coincide with the first parameter in Urldata - it will be a router, $ Router. And from Urldata This router must be removed, it is no longer needed and is used only to connect the desired file. array_Slice ($ URLS, 1) And it will pull us all the elements of the array, except for the first.

Now it remains to connect the desired router file and run the Route function with three parameters. What is this Function Route? We agree that in each router file, this function will be defined, which by the input parameters determine which action the user initiated, and execute the desired code. Now it will become clearer. Consider the first request - receiving data on the product.

Get / Goods / (GOODID)

Routers / goods.php file

// Router Function Route ($ Method, $ Urldata, $ FormData) (// Receive Product Information // Get / Goods / (GoodID) if ($ Method \u003d\u003d\u003d "Get" && Count ($ Urldata) \u003d\u003d\u003d 1) (// Get the product ID $ goodid \u003d $ urldata; // pull out the goods from the base ... // withdraw the answer to the Echo JSON_ENCODE client (array ("Method" \u003d\u003e "Get", "id" \u003d\u003e $ goodid, "Good" \u003d\u003e "Phone", "Price" \u003d\u003e 10000)); return;) // Return the HEADER error ("HTTP / 1.0 400 Bad Request"); Echo JSON_ENCODE (Array ("Error" \u003d\u003e "Bad Request "));)

The contents of the file is one large ROUTE function, which, depending on the parameters transmitted, performs the necessary actions. If the GET method and Urldata transmitted 1 parameter (GOODID), then this is a request for data on the product.

Attention: an example is very simplified
In real life, of course, you need to additionally check the input parameters, for example, that GOODID is a number. Instead of writing the code here, you probably connect the desired class. And to get the item, create an object of this class and cause it some method.
Or maybe give the control of some controller, which is already concerned with the initialization of the desired models. There are many options, we consider only the general structure of the code.

In response to the client, we derive the necessary data: the name of the goods and its price. The product ID and method in real appendix are not completely mandatory. We will show them only to make sure that the desired method is called with the correct parameters.

Let's try on the example: Open the browser console and execute the code.

$ .Ajax ((URL: "/ Examples / Rest / Goods / 10", Method: "Get", Datatype: "JSON", Success: Function (Response) (Console.log ("Response:", Response))) )

The code will send a request to the server where I unfolded a similar application and displays the answer. Make sure our route / Goods / 10 really worked. On the NetWork tab, you will notice the same query.
And yes, / ExamPles / Rest is the root path of our test application to the site

If you are familiar to using the curl in the console, then run it in the terminal - the answer will be the same, and even with the headers from the server.

CURL -X GET HTTPS: // Site / Examples / REST / Goods / 10 -i

At the end of the function, we wrote such a code.

// Return the HEADER error ("HTTP / 1.0 400 Bad Request"); ECHO JSON_ENCODE (Array ("Error" \u003d\u003e "Bad Request"));

It means that if we are mistaken with the parameters or the requested route is not defined, then we return the client 400-m Bad Request. Add, for example, to the URL, something like goods / 10 / Another_param And you will see a bug in the console and the answer 400 - the curve is not a request.

On server responses http-codes
We will not bother with the withdrawal of different codes, although on the REST, it is worth doing. Client errors are a lot. Even in our simple case, 405 is appropriate in the case of an incorrectly transmitted method. I intentionally do not want to complicate.
In case of success, the server will always return 200 OK. For good, when creating a resource is worth the 201 Created. But again, in terms of simplification, these subtleties we will throw, and in the real project you easily implement themselves.

According to conscience, the article is completed. I think you have already understood the approach, how all the routes are destroyed, the data is taken out, how to test, how to add new requests, etc. But I will bring the implementation of the remaining 7 requests that we identified at the beginning of the article. Along the way, I will bring a couple of interesting comments, and at the end lay the archive with the source.

POST / GOODS.

Adding a new product

// Adding a new product // post / goods if ($ Method \u003d\u003d\u003d "POST" && empty ($ urldata)) (// add goods to the database ... // Display the answer to the Echo JSON_ENCODE client (Array ("Method" \u003d\u003e "POST", "ID" \u003d\u003e RAND (1, 100), "FormData" \u003d\u003e $ FormData)); Return;)

urldata is now empty, but FormData is used - we simply bring it to the client.

How to make "right"?
According to the REST canons in the post query, you should give back only the ID of the created entity or URL, according to which this entity can be obtained. That is, there will be a response or just a number - (Goodid), or / Goods / (Goodid).
Why did I write "right" in quotes? Yes, because REST is a set of not tough rules, but recommendations. And as you will implement you, it depends on your preferences or already accepted agreements on a specific project.
Simply keep in mind that another programmer reading code and aware of the REST approach will be expected to respond to a post-request ID of the created object or the URL, which can be obtained by the GET request to pull out the data about this object.

Testing from console

$.ajax ((URL: "/ Examples / REST / Goods /", Method: "POST", DATA: (Good: "Notebook", Price: 20,000), Datatype: "JSON", Success: Function (Response) ( Console.log ("Response:", Response))))

CURL -X POST HTTPS: // Site / Examples / REST / Goods / --data "Good \u003d Notebook & Price \u003d 20000" -i

PUT / GOODS / (GoodID)

Editing goods

// Upgrading All Data Products // Put / Goods / (GoodID) if ($ Method \u003d\u003d\u003d "PUT" && Count ($ Urldata) \u003d\u003d\u003d 1) (// Get the product ID GOODID \u003d $ Urldata; // We update all fields of goods in the database ... // Display the answer to the Echo JSON_ENCODE client (Array ("Method" \u003d\u003e "Put", "id" \u003d\u003e $ goodid, "FormData" \u003d\u003e $ FormData)); Return;)

Here, all data is used in full. From Urldata, the product ID is pulled out, and from FormData properties.

Testing from console

$ .ajax ((URL: "/ ExamPles / REST / Goods / 15", Method: "Put", Data: (Good: "Notebook", Price: 20,000), Datatype: "JSON", Success: Function (Response) (Console.log ("Response:", Response))))

CURL -X PUT HTTPS: // Site / Examples / REST / Goods / 15 --data "Good \u003d Notebook & Price \u003d 20000" -i

Patch / Goods / (GoodID)

Partial updating of goods

// Partial service update // Patch / Goods / (GoodID) if ($ Method \u003d\u003d\u003d "Patch" && Count ($ urldata) \u003d\u003d\u003d 1) (// Get the product ID $ goodid \u003d $ urldata; // We update only the specified fields of the goods in the database ... // Display the answer to the Echo JSON_ENCODE client (Array ("Method" \u003d\u003e "Patch", "id" \u003d\u003e $ goodid, "FormData" \u003d\u003e $ FormData)); Return;)

Testing from console

$ .Ajax ((URL: "/ EXAMPLES / REST / GOODS / 15", Method: "Patch", Data: (Price: 25000), DataType: "JSON", Success: Function (Response) (Console.log (" Response: ", Response))))

CURL -X PATCH HTTPS: // Site / Examples / Rest / Goods / 15 --data "Price \u003d 25000" -i

What are these Ponte with Put and Patch?
Is one PUT not enough? Do not they perform the same action - update the object data?
That is how one thing is one. The difference in the transmitted data.
Put assumes that the server is transmitted everything Fields of the object, and Patch - only changed. Those that are transmitted in the query body. Please note that in the previous Put we also transferred the name of the goods and the price. And in Patch - only the price. That is, we sent only changed data to the server.
Do you need PATCH - decide for yourself. But remember the reading programmer code, which I mentioned above.

DELETE / GOODS / (GoodID)

Removing goods

// Delete goods // Delete / Goods / (GoodID) if ($ Method \u003d\u003d\u003d "Delete" && Count ($ Urldata) \u003d\u003d\u003d 1) (// Get the product ID $ goodid \u003d $ urldata; // Remove the goods From the base ... // Display the answer to the Echo JSON_ENCODE client (array ("Method" \u003d\u003e "Delete", "id" \u003d\u003e $ goodid)); return;)

Testing from console

$ .Ajax ((URL: "/ ExamPles / REST / GOODS / 20", Method: "Delete", Datatype: "JSON", Success: Function (response) (Console.log ("Response:", Response))) )

CURL -X DELETE HTTPS: // Site / Examples / REST / GOODS / 20 -I

With a delete request, everything is clear. Now let's look at work with users - router Users and, accordingly, the user.php file

Get / Users / (UserID)

Obtaining all user data. If the type get-request / Users / (UserID), then we will refund all the information about the user if it is additionally indicated / info. or / Orders., accordingly, only general information or a list of orders.

// Router Function Route ($ Method, $ Urldata, $ FormData) (// Get all user information // Get / Users / (UserID) if ($ Method \u003d\u003d\u003d "Get" && Count ($ Urldata) \u003d\u003d \u003d 1) (// Get the product ID userID \u003d $ urldata; // pull out all user data from the database ... // Display the answer to the ECHO JSON_ENCODE client (Array ("Method" \u003d\u003e "Get", "id" \u003d \u003e $ UserID, "info" \u003d\u003e Array ("Email" \u003d\u003e " [Email Protected]"," NAME "\u003d\u003e" WebDevkin ")," Orders "\u003d\u003e Array (Array (" Order "\u003d\u003e 5," Summa "\u003d\u003e 2000," OrderDate "\u003d\u003e" 01/12/2017 "), Array (" Orderid "\u003d\u003e 8," Summa "\u003d\u003e 5000," OrderDate "\u003d\u003e" 03.02.2017 ")))); return;) // Return the HEADER error (" HTTP / 1.0 400 Bad Request "); Echo JSON_ENCODE ( Array ("Error" \u003d\u003e "Bad Request"));)

Testing from console

$ .Ajax ((URL: "/ EXAMPLES / REST / Users / 5", Method: "Get", Datatype: "JSON", Success: Function (Response) ("Response:", Response))) )

CURL -X GET HTTPS: // Site / Examples / Rest / Users / 5 -i

Get / Users / (UserID) / Info

General information about the user

// Obtaining general user information // Get / Users / (UserID) / Info if ($ Method \u003d\u003d\u003d "Get" && Count ($ Urldata) \u003d\u003d\u003d 2 && $ urldata \u003d\u003d\u003d "info") (/ / Get the product of the product $ userid \u003d $ urldata; // pull out the general user data from the database ... // Display the answer to the Echo JSON_ENCODE client (array ("Method" \u003d\u003e "Get", "id" \u003d\u003e $ UserID, " info "\u003d\u003e array (" email "\u003d\u003e" [Email Protected]"," Name "\u003d\u003e" WebDevkin "))); return;)

Testing from console

$ .Ajax ((URL: "/ EXAMPLES / REST / USERS / 5 / INFO", Method: "Get", Datatype: "JSON", Success: Function (Response) (Console.log ("Response:", Response) )))

CURL -X GET HTTPS: // Site / Examples / Rest / Users / 5 / Info -i

Get / Users / (UserID) / Orders

Getting a list of user orders

// Receiving user orders // Get / Users / (UserID) / Orders if ($ Method \u003d\u003d\u003d "Get" && Count ($ Urldata) \u003d\u003d\u003d 2 && $ urldata \u003d\u003d\u003d "Orders") (// Get Product ID $ UserID \u003d $ urldata; // pull out the user order data from the database ... // Display the answer to the Echo JSON_ENCODE client (array ("Method" \u003d\u003e "Get", "id" \u003d\u003e $ Userid, "Orders" \u003d\u003e Array (Array ("order" \u003d\u003e 5, "summa" \u003d\u003e 2000, "OrderDate" \u003d\u003e "12.01.2017"), array ("OrderID" \u003d\u003e 8, "Summa" \u003d\u003e 5000, "OrderDate "\u003d\u003e" 03.02.2017 ")))); Return;)

Testing from console

$ .Ajax ((URL: "/ Examples / Rest / Users / 5 / Orders", Method: "Get", Datatype: "JSON", Success: Function (Response) (Console.log ("Response:", Response) )))

CURL -X GET HTTPS: // Site / Examples / Rest / Users / 5 / Orders -i

Results and sources

Sources from examples of the article -

As you can see, to organize support for the REST API on the native PHP turned out to be not so difficult and completely legitimate. The main thing is to support routes and non-standard PHP methods PUT, PATCH and DELETE.

The main code that implements this support was fitted at 3 tens of index.php rows. The rest is already a strainer that can be realized as you like. I suggested this in the form of connected router files, the names of which coincide with the entities of your project. But you can connect fantasy and find a more interesting solution.

In the second lesson, we will write two more classes and completely finish the inner part of the script.

Plan

The purpose of the lesson series to create a simple application that allows users to register, enter, exit and change settings. A class that will contain all user information will be called user and it will be defined in the user.class.php file. A class that will be responsible for input \\ output will be called userTools (usertools.class.php).

A little about the name of the classes

The correct tone is to call files with a class description as the same name as the class itself. Thus it is easy to determine the purpose of each file in the folder with classes.

Also, at the end of the name of the class file, add.class or.inc. Thus, we clearly define the purpose of the file and can use.htaccess to restrict access to these files.

Users class (user.class.php)

This class will define each user. With the growth of this application, the definition "user" can change significantly. Fortunately, OOP Programming makes it easy to add additional user attributes.

Constructor

In this class, we will use the constructor - this is a function that is automatically called when creating another copy of the class. This allows us to automatically publish some attributes after creating a project. In this class, the designer will take the only argument: an associative array that contains one row from the users table of our database.

REQUIRE_ONCE "DB.CLASS.PHP"; Class User (Public $ ID; Public $ Username; Public $ HashedPassword; Public $ email;
public $ joindate;
//The designer is called when creating a new object // Takes An Associative Array with the DB Row AS An Argument. FUNCTION __CONSTRUCT ($ DATA) ($ this-\u003e ID \u003d (ISSET ($ Data [ID "]))? $ Data [ID"]: ""; $ this-\u003e UserName \u003d (ISSET ($ Data [" UserName "]))? $ data [" UserName "]:" "; $ this-\u003e hashedpassword \u003d (ISSET ($ Data [" Password]))? $ Data ["Password"]: ""; $ THIS- \u003e email \u003d (issset ($ data ["email"]))? $ data ["Email"]: ""; $ this-\u003e JOINDATE \u003d (ISSET ($ DATA ["join_date]))? $ DATA [" join_date "]:" ";)
Public Function Save ($ isnewuser \u003d false) (// Create a new Database Object. $ db \u003d new db (); // if the user is already registered and we "re // Just Updating their info. if (! $ isnewuser ) (// Set the Data Array $ Data \u003d Array ("Username" \u003d\u003e "" $ this-\u003e username "", "password" \u003d\u003e "" $ this-\u003e hashedpassword "",
"Email" \u003d\u003e "" $ this-\u003e email "");
// Update The Row in the Database $ db-\u003e Update ($ Data, "Users", "id \u003d". $ this-\u003e id); ) ELSE (// if the user is being registered for the first time. $ data \u003d array ("username" \u003d\u003e "" $ this-\u003e username "", "password" \u003d\u003e "" $ this-\u003e hashedpassword "" , "Email" \u003d\u003e "" $ this-\u003e email "", "join_date" \u003d\u003e "" .date ("YMD H: I: S", Time ()). "" "); $ this-\u003e id \u003d $ DB-\u003e INSERT ($ data, "users"); $ this-\u003e joindate \u003d time ();) Return True; ))?\u003e

Explanation

The first part of the code, outside the class zone, provides a connection of the class in the database (since the user class has a function that requires this class).

Instead of class variables "Protected" (used in the 1st lesson), we define them as "Public". This means that any code outside the class has access to these variables when working with the user object.

The designer takes an array in which the columns in the table are keys. We specify a class variable using $ this-\u003e variablename. In the example of this class, we first check whether the value of a specific key is. If so, then we equate the class variable to this value. Otherwise, an empty string. The code uses a brief form of an IF turnover:

$ Value \u003d (3 \u003d\u003d 4)? "A": "B";

In this example, we check whether 3 fours is equal to 3! If yes - then $ Value \u003d "A", no - $ value \u003d "b". In our example, the result is $ value \u003d "b".

We save information about users in the database

The save feature is used to make changes to the database table with current values \u200b\u200bin the User object. This feature uses the BD class, which we created in the first lesson. Using class variables, an array of $ DATA is installed. If the user data is saved for the first time, then $ isnewuser is transmitted as $ true (default FALSE). If $ isnewuser \u003d $ true, then the INSERT () DB class function is called. Otherwise, the Update () function is called. In both cases, information from the user object will be saved in the database.

USERTOOLS.CLASS.PHP class

This class will contain functions that are related to users: login (), logout (), checksernameexists () and get (). But with the extension of this application, you can add many other others.

//Usertools.class.php Require_ONCE "user.class.php"; REQUIRE_ONCE "DB.CLASS.PHP";
class Usertools (
// Log The User in. FIRST CHECKS TO SEE IF THE // UserName and Password Match a Row in the Database. // If IT Is Successful, Set The Session Variables // and Store The User Object Within.
public Function Login ($ Username, $ Password)
{
$ hashedpassword \u003d MD5 ($ password); $ result \u003d mysql_query ("select * from users where username \u003d" $ username "and password \u003d" $ hashedpassword "); if (mysql_num_rows ($ result) \u003d\u003d 1) ($ _session ["user"] \u003d Serialize (NEW User (MYSQL_FETCH_ASSOC ($ RESULT)); $ _session ["login_time"] \u003d time (); $ _session ["Logged_in "] \u003d 1; Return True;) ELSE (RETURN FALSE;))
// Log The User Out. Destroy The Session Variables. public function logout () (Unset ($ _ session ["user"]); unset ($ _ session ["login_time"]); unset ($ _ session ["Logged_in"]); session_destroy ();) // Check to See if if iF A username exists. // This Is Called During Registration To Make Sure All User Names Are Unique. Public Function CheckUnameExists ($ UserName) ("" SELECT \u003d MYSQL_Query ("SELECT ID FROM Users WHERE username \u003d" $ username ""); if (mysql_num_rows ($ result) \u003d\u003d 0) (Return False) ELSE (Return True;)
}
// Get A user // Returns a user Object. Takes The Users ID AS An Input Public Function Get ($ ID) ($ db \u003d new db (); $ result \u003d $ db-\u003e select ("Users", "id \u003d $ id"); Return new user ($ result );))
?>

Login () function

The Login () function is clear by the name. It takes the $ username and $ password user arguments and checks them. If everything matches, creates an User object with all information and saves it in the session. Please note that we only use the PHP Serialize () function. It creates a saved version of the object that can be easily canceled using unservialize (). Also, the login time will be saved. This can be used in the future to provide users with information on the duration of stay on the site.

You may also notice that we set $ _session ["Logged_in"] to 1. This allows us to easily check on each page login logically. It is enough to check only this variable.

LogOUT ()

Also a simple feature. The PHP Unset () function clears the variables in memory, while session_destroy () deletes the session.

Function CheckUserNameExists ()

Who knows English will easily understand the function. It simply requests the database, whether similar login is used or not.

GET () function

This feature takes a unique user ID and makes a query to the database using class DB, namely SELECT () functions. It will take an associative array with a number of user information and create a new User object, transmitting an array to the designer.

Where can I use it? For example, if you create a page that should display specific user profiles, you will need to dynamically take this information. This is how you can do this: (I will say ul http://www.website.com/profile.php?userid\u003d3)

// Note: You Will Have to Open Up a Database Connection First. // See Part 1 for Further Information on Doing SO. // You "LL ALSO Have to make sure that you" Ve Included The Class Files.
$ Tools \u003d New UserTools (); $ User \u003d $ Tools-\u003e Get ($ _ require ["UserID"]); Echo "UserName:". $ User-\u003e UserName. ""; Echo "JoinD on:". $ User-\u003e JOINDATE. "";

Easily! Truth?

Last Stroke Server Part: Global.Inc.php

global.inc.php is required for each page of the site. Why? Thus, we will place all the usual operations that we need on the page. For example, we will start session_start (). BD connection will also open.

require_ONCE "CLASSES / USERTOOLS.CLASS.PHP";
require_ONCE "CLASSES / DB.CLASS.PHP";
// Connect to the database $ db \u003d new db (); $ DB-\u003e CONNECT ();
// initialize UserTools Object $ userTools \u003d new usertools (); // Start The Session
session_start ();
// Refresh Session Variables IF Logged in If (ISSET ($ _ session ["Logged_in])) ($ User \u003d UnserIalize ($ _ session [" user "]); $ _session [" User "] \u003d Serialize ($ UserTools-\u003e Get ($ User-\u003e ID));)?\u003e

What does he do?

There is a few things here. First of all, we open a connection to the base.

After the connection, we begin the session_start () function. The function creates a session or continues the current if the user is already logged in. Since our application is designed for users to enter \\ out, this feature is mandatory on each page.

Next, we check whether the user is logvined. If yes - we will update $ _Session ["User"] to display the latest information about user. For example, if the user changes his email, an old one will be stored in the session. But with the help of the auto update this will not happen.

On this, the second part came to the end! Tomorrow expect the final lesson on this topic.

All the best!

Gets the WP_USER object, which contains all the data of the specified user.

The data returned functions fully correspond to the database table fields: WP_USERS and WP_USERMETA (table descriptions).

This is a pluggable function - i.e. It can be replaced from the plugin. This means that it will work (connected) only after connecting all plug-ins, and up to this point the function is not yet defined ... Therefore, it is impossible to call this function dependent on it directly from the plug-in code. They need to be called through the Hook plugins_loaded or later, for example, Hook Init.

Replacing the function (redefinition) - in the plugin you can create a function with the same name, then it will replace the current function.

✈ 1 time \u003d 0.000296c \u003d fast | 50000 times \u003d 0.78c \u003d very fast | PHP 7.1.2RC1, WP 4.7.2

No hooks.

Returns

WP_USER / FALSE. Data object or false, if not managed to find the specified user.

Using

get_userdata ($ UserID); $ Userid. (number) (mandatory) The user ID whose data needs to be obtained.
Default: No

Examples

# 1 How to output data from the data object received

$ user_info \u003d get_userdata (1); Echo "Username:". $ user_info-\u003e user_login. "\\ n"; Echo "Access Level:". $ user_info-\u003e user_level. "\\ n"; Echo "ID:". $ user_info-\u003e ID. "\\ n"; / * Will out: Username: Admin Access Level: 10 ID: 1 * /

# 1.2 Data in the variable

Another example, only here I will write data first into variables, and then remove from the screen:

$ user \u003d get_userdata (1); $ username \u003d $ user-\u003e user_login; $ first_name \u003d $ user-\u003e first_name; $ Last_Name \u003d $ User-\u003e Last_Name; Echo "$ first_name $ last_name went to the site under login: $ username."; / * Object $ User: WP_USER OBJECT (\u003d\u003e STDCLASS OBJECT (\u003d\u003e 80 \u003d\u003e KOGIAN \u003d\u003e $ p $ bjfhkjfukywv1twallsNYU0JGNSQ. \u003d\u003e KOGIAN \u003d\u003e [Email Protected] \u003d\u003e http://example.com/ \u003d\u003e 2016-09-01 00:34:42 \u003d\u003e \u003d\u003e \u003d\u003e kogian) \u003d\u003e 80 \u003d\u003e array (\u003d\u003e 1) \u003d\u003e WP_CAPABILITIES \u003d\u003e Array (\u003d\u003e Subscriber) \u003d\u003e array (\u003d\u003e 1 \u003d\u003e 1 \u003d\u003e 1) \u003d\u003e \u003d\u003e 1) * /

# 2 class methods

The resulting object with get_userdata () is an instance of the class and it has methods that can be used. Sometimes it can come in handy. Here is a simple example of obtaining the user option, using the $ User-\u003e Get () method:

$ user \u003d get_userdata (1); echo $ username \u003d $ user-\u003e get ("user_login");

List of some methods:

    get ($ Key) - return the value of the option;

    hAS_PROP ($ Key) - checks whether the specified option is installed;

    hAS_CAP ($ CAP) - Checks whether the user has the specified possibility or role;

    get_role_caps () - gets all the features of the user's role and combines them with individual user capabilities;

    add_role ($ Role) - adds role to the user;

    remove_role ($ Role) - removes the role of the user;

  • set_role ($ Role) - sets the role of the user;

Notes

Here are some useful values \u200b\u200bof the WP_USERS and WP_USERMETA tables, which you can use to obtain data:

  • display_name.

user_Meta.

  • user_Description.

    wP_CAPABILITIESES (array)

    admin_Color (Theme Admin Panel. Default - Fresh (Fresh))

    closedPostboxes_page.

  • source_domain.

It also needs to be noted that from version 3.2., The returned data has changed a bit: the WP_USER object is returned. The data in the object is divided into groups: Data, Caps, Roles (earlier, the data was returned in the overall list).

However, thanks to the "magic" (service) methods of PHP, data can be obtained as before, for example, now the data is stored as follows: Get_userData (1) -\u003e Data-\u003e Rich_Editing, but you can get them like this: get_userdata (1) -\u003e Rich_EnData, Despite the fact that VAR_DUMP () will not show this relationship.

The code get UserData: WP-includes / pluggable.php WP 5.2.2

document.write("");
Did you like the article? To share with friends: