[译]"世界上最快的服务器"跟踪(提交应用程序挑战)
By robot-v1.0
本文链接 https://www.kyfws.com/applications/the-world-s-fastest-server-tracking-application-ch-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 9 分钟阅读 - 4176 个词 阅读量 0[译]"世界上最快的服务器"跟踪(提交应用程序挑战)
原文地址:https://www.codeproject.com/Articles/34366/The-World-s-Fastest-Server-Tracking-Application-Ch
原文作者:phparray
译文由本站 robot-v1.0 翻译
前言
Using PHP-SOAP to access the world’s fastest server web service and plot each trip using the Google maps API 使用PHP-SOAP访问世界上最快的服务器Web服务并使用Google Maps API绘制每次行程
- 下载源100.06 KB(Download source - 100.06 KB)
- 下载源(外部链接)-100.06 KB(Download source (external link)- 100.06 KB)
- 示范项目(Demo project) ## 介绍(Introduction) 该Web应用程序是The Code Project和Hostmysite.com共同提出的挑战中的一个条目.作为一名狂热的摩托车爱好者和Web应用程序开发人员,这项比赛就在我的小巷.我开发的应用程序也受到了我在2008年夏天编写的Baja竞赛跟踪应用程序的启发.在整篇文章中,将对与该应用程序相关的术语进行解释,例如OOP,SOAP和SJAX.有关这些术语的更多常规信息,请参见PHP.NET,Google.com以及在The Code Project上的其他文章.(This web application is an entry in the joint challenge put out by The Code Project and Hostmysite.com. As an avid Motorcycle enthusiast and web application developer, this contest is right up my alley. The application I have developed is also somewhat inspired by a Baja race tracking application I wrote in the summer of 2008. Throughout the article, terms like OOP, SOAP, and SJAX will be explained as they relate to the application. For more general information regarding these terms, see PHP.NET, Google.com, and other articles found here on The Code Project.)
背景(Background)
对于阅读和自问的人来说,您所说的挑战是什么?更多信息可以在这里找到:(For anyone reading and asking themselves, what is this challenge you speak of? More information can be found here:) 全球最快的服务器挑战(World’s Fastest Server Challenge) .(.) 还是很困惑,结帐:(Still confused, checkout:) 世界上最快的服务器(The World’s Fastest Server) .(.) 该应用程序使用世界上最快的服务器Web服务,Google Maps API和带有SOAP的PHP在Google Map上绘制路线,最新位置和accell数据.(This application uses the World’s Fastest Server web service, the Google Maps API, and PHP with SOAP to plot its course, latest position, and accell data on a Google Map.)
使用代码(Using the Code)
PHP没有规则.我发现自己在对编程语言和最佳实践进行比较的对话中经常说这句话.使用像PHP这样的"松散"语言既是福也是祸.希望当您使用此代码时,无论您尝试执行什么操作,您都会发现我的OOP方法可高度重用于任何应用程序.(PHP has no rules. I find myself saying that very sentence time and time again in conversations comparing programming languages and best practices. It is both a blessing and curse to use a language as “loose” as PHP. Hopefully when you are using this code, you will find my method of OOP highly reusable for any application regardless of what you are attempting to do.) 要运行此应用程序,您的PHP服务器必须具有可用的SOAP.(To run this application, your PHP server must have SOAP available.)** http://us.php.net/manual/zh/book.soap.php(http://us.php.net/manual/en/book.soap.php) ** 此应用程序的基本目录结构:(*The basic directory structure of this application:*)
- index.php(index.php)(UI)((UI))
- js/(js/)
- ajax.js(ajax.js)(我的ajax库)((my ajax library))
- map.js(map.js)(加载初始地图)((loads the initial map))
- scripts.js(scripts.js)(接受来自用户界面的调用)((accepts calls from the UI))
- 包括/(includes/)
- config.ini(config.ini)(存储环境信息)((stores environmental info))
- application.php(application.php)(在PHP请求上处理的第一个文件)((first file processed on PHP requests))
- 班级/(classes/)
- global_class.php(global_class.php)(此类成员可以在任何地方使用)((members of this class may be used anywhere))
- Calls.php(calls.php)(此类的成员特定于调用Web服务)((members of this class are specific to calling the web service))
- 输出/(output/)(这些文件被接受并以纯文本格式响应HTTP请求)((these files are accepted and respond to HTTP requests with plain text))
- accel.php(accel.php)
- latlng.php(latlng.php)
- polyline.php(polyline.php)
使用PHP配置文件格式使任何人都可以轻松设置应用程序.这是唯一需要编辑才能在其他环境中运行的应用程序的文件.(Using a PHP configuration file format makes setting up your application easy for anyone. This is the only file that requires editing for the app to run in another environment.)
//config.ini
[service]
wsdl="http://www.theworldsfastestserver.com/webservice/bikedata.cfc?wsdl"
[environment]
;a windows path would generally start with c:\
;a linux path would generally start with /var/www/html
doc_root="/path/from/server/root"
web_root="http://mydomain.tld/path/to/app"
[google]
;get your key here http://code.google.com/apis/maps/signup.html
apikey="your own google api key goes here"
兴趣点(Points of Interest)
如果一个文件比其他文件更重要,则必须(If one file was more important than the others, it would have to be)application.php(application.php).在其中,您会发现(. Within it, you will find the use of) __autoload()
,这很可能是我使用OOP(面向对象编程)所学到的最有用的东西.使用(, what could very well be the most helpful thing I have learned for using OOP (object oriented programming). Using) __autoload()
避免需要跟踪可能会变成包含文件的长列表的内容.创建在生成错误之前未找到的类的实例时(prevents the need to keep track of what can become long lists of include files. When creating an instance of the class that is not found before an error is generated) __autoload()
会跑.所有需要的是类名与文件名匹配.您可以在输出目录中的任何文件中看到此操作.(will run. All that is required is the class names match the file names. You can see this in action within any of the files in the output directory.)
//application.php
#set display_errors on for testing off for production
ini_set('display_error','On');
error_reporting(E_ALL ^ E_STRICT);
#parse custom ini file
$config = parse_ini_file('config.ini');
#define constants from ini file
define(WSDL,$config['wsdl']);
define(WEB_ROOT,$config['web_root']);
define(DOC_ROOT,$config['doc_root']);
define(GOOGLE_API_KEY,$config['apikey']);
#auto load all classes
require_once('classes/global_class.php');
$global_class = new global_class();
function __autoload($class_name) {
require_once (DOC_ROOT.'/includes/classes/'.$class_name.'.php');
}
**index.php(index.php)**是应用程序的用户界面.这是最终用户直接看到的唯一页面.您会看到(is the user interface for the application. This is the only page end users see directly. You will see the)**index.php(index.php)**文件主要包含HTML标记.我没有设计样式,只是为了使事情专注于实际的应用程序,而不是它的外观.当然,在商业用途中,可以非常轻松地添加CSS文件,使外观更加生动.(file contains mostly HTML markup. I have not styled it in an effort to keep things focused on the actual application and not how pretty it is. Of course in commercial use, a CSS file could be added very easily and liven things up nicely.)
//index.php
//I am only mentioning the important part of the index.php file here.
//The complete code is in the zip file available for download.
//always process the application file first
require_once('includes/application.php');
//create and instance of the calls class.
//Because of _autoload() I do not have to include the class file
//but calls.php needs to exist in my includes/classes folder
$calls = new calls();
//Don't forget you need a Google maps API key but we stored that in our config.ini file
<script src="http://maps.google.com/maps?
file=api&v=2&sensor=true&key=<?=GOOGLE_API_KEY?>" type="text/javascript"></script>
//load the javascript files
<script type="text/javascript" src="http://www.codeproject.com/fast/js/ajax.js">
</script>
<script type="text/javascript"
src="http://www.codeproject.com/fast/js/scripts.js"></script>
<script type="text/javascript" src="http://www.codeproject.com/fast/js/map.js"></script>
//GetTripIDs is a member of the calls class.
//It will use the web server to create a drop down box of trips
$calls->GetTripIDs();
//javascript needs this dom objects I am using output to display errors
<span id="output"></span>
//accelerometer data will appear here
<div id="accel"></div>
//the map will appear here
<div id="latlng"></div>
**global_class.php(global_class.php)**用于可能从任何地方调用的方法.对于此应用程序,这里需要两个功能.(is used for methods that may be called from anywhere. For this application, I have needed two functions here.)
//global_class.php
class global_class {
//utctotime converts the utc formatted timestamp from the
//bike's web service into a more human readable data
function utctotime($utc,$format)
{
setlocale(LC_TIME, 'en_US');
$da = explode("T",$utc);
$un = strtotime($da[0]);
$time = date($format,$un);
return $time;
}
//client creates an instance of a SoapClient object
function client($wsdl)
{
$client = new SoapClient($wsdl);
return $client;
}
}
**Calls.php(calls.php)**包含我们在上面看到的功能(contains the function we saw used above) GetTripIDs()
.(.) GetTripIDs()
首先创建一个(will first create the instance of a) SoapClient
对象,然后调用Web服务功能(object then call the web service function) GetTripIDs
返回所有行程.现在您可以看到选择框的来源.您还可以看到我正在使用onchange事件处理程序来触发JavaScript函数(to return all trips. Now you can see where the select box comes from. You can also see I am using an onchange event handler to trigger a JavaScript function) waypoints()
.(.)
//calls.php
function GetTripIDs()
{
$client = $this->client(WSDL);
$return = $client->GetTripIDs();
if(is_soap_fault($return))
return trigger_error("SOAP Fault:
(faultcode: {$result->faultcode},
faultstring: {$result->faultstring})",
E_USER_ERROR);
else
{
$options = '<option value="">
Select a trip</option>';
foreach($return->data as $key => $val)
{
$options .=
'<option value="'.$val[0].'">'.
$val[2].'</option>';
}
$form = '<select onchange="waypoints(\'latlng\',
this.value)" name="tripId">
'.$options.'
</select>';
return $form;
}
}
这是事情开始变得更加有趣的地方.我用(This is where things start to get more interesting. I use)**ajax.js(ajax.js)**作为ajax的库.在此应用程序中,您将看到(as a library for ajax. In this application, you will see the) getFile()
JavaScript函数多次使用.当我说SJAX时,您可能一开始也挠了一下头.没错,使用异步调用并不总是有用.有时就像我们的情况一样,呼叫需要同步.一个常见的错误是将异步视为仅与初始页面加载和后续调用之间的分离.尽管异步JavaScript确实意味着这一点,但它也意味着,如果在其他JavaScript操作列表中调用该线程,则会分离出一个单独的线程.例如,如果我在(JavaScript function used multiple times. You also may have scratched your head a little in the beginning when I said SJAX. That is right it is not always useful to use asynchronous calls. Sometimes like in our case, the call needs to be synchronous. A common mistake is to think of asynchronous as only the separation from the initial page load and subsequent calls. While asynchronous JavaScript does mean that, it also means a separate thread is spun off if invoked during a list of other JavaScript operations. For example if I invoke something asynchronous during a) for
循环,我不能再依赖该调用返回的任何内容作为循环的条件.相反,当我确实需要循环来等待调用返回信息时,这两个操作将同时运行.(loop, I can no longer rely on anything returning from that call as a condition of my loop. Instead the two operations will be running at the same time when I really need the loop to wait for my call to return with information.)
中(Within)ajax.js(ajax.js), 你会看见(, you will see) getFile()
和(and) get()
.(.)
//getFile() is synchronous because of the line open("POST",url,false); notice the false.
//get() is asynchronous because of the line open("POST",url,true); notice the true.
getFile()
以同步方式从HTTP请求返回文本,而(returns the text from the HTTP request in a synchronous manner while) get()
将文本输出到(outputs the text to a) dom
异步对象.我必须使用同步选项,因为我无法拥有我的(object asynchronously. I have to use the synchronous option because I cannot have my) waypoint()
通过返回信息在HTTP请求完成之前继续执行该功能.在第一个电话中(function continuing before the HTTP request finishes by returning information. In the first call to) getFile
,(, the)**latlng.php(latlng.php)**文件将被处理.它将返回从(file will be processed. It will return the last latitude and longitude decimal value obtained from the) GetWaypointsForTrip()
所选行程的网络服务电话.什么时候(web service call for the trip selected. When) waypoints()
到达(gets to the) //get accel data
行,我用(line, I use) getFile()
再次但这次运行(again but this time to run)accel.php(accel.php).此调用的响应将是包含所有纬度和经度十进制值的CSV字符串.然后将CVS数据解析并转换为数组(. The response from this call will be a CSV string of all the latitude and longitude decimal values. The CVS data is then parsed and turned into an array of) Glatlng()
每个Google Maps API对象创建折线.(objects per the Google maps API to create the polyline.)
//scripts.js
//this is the waypoints function called from the onchange event of our select box
//from the select box the first parameter file is defined as latlng and the second
//is this.value (the value of the field after it was changed).
//latlng will be used by getFile as latlng.php found in the output directory.
function waypoints(file,id)
{
var latlng = getFile(file,id,null);
if(latlng != 0 && latlng.match(",") != null)
{
var ll = latlng.split(",");
var lat = ll[0];
var lng = ll[1];
//clear map overlays
map.clearOverlays();
document.getElementById('accel').innerHTML = '';
//set map center
map.setCenter(new GLatLng(lat, lng), 16);
var point = new GLatLng(lat, lng);
var marker = new GMarker(point);
//get accel data
var html = getFile('accel',id,null);
//output accel data
document.getElementById('accel').innerHTML = html;
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(html);
});
map.addOverlay(marker);
//add polyline to map
var linearray = polyline(id);
if(linearray!=0)
map.addOverlay( new GPolyline
( linearray, '#66FF00', 2, 1 ) );
//clear any previous data from the
//output dom object.
document.getElementById('output').innerHTML = '';
}
else
{
//write any errors to the output dom object
var message = 'No waypoints for this trip';
document.getElementById('output').innerHTML =
message;
}
}
我希望您下载此应用程序并将其修改为您的满意的内容.这样,您将重新执行本文中已阅读的内容,并且肯定会学到更多的知识,而不是仅通过阅读即可完成.您可以随意使用任何此代码.请享用.(I hope that you download this application and modify it to your hearts content. By doing so, you will re enforce what you have read within this article and certainly learn more than what can be accomplished by reading alone. You are free to use any of this code however you like. Enjoy.)
历史(History)
- 20(20)日(th)2009年3月:初始版本(March, 2009: Initial version)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
Javascript Linux Windows PHP Dev 新闻 翻译