请参阅下面的编辑
我正在尝试深入研究 PHP 中的 OOP 开发,但我真的开始感到头痛或溃疡。我只是无法理解它,有些部分对我来说太不合逻辑了,而且我不知道从哪里开始,这真的让我很沮丧,因为我相信尝试学习它是值得的,它为我提供了更好的概述关于我的代码。
<罢工>
昨天在网上找了一整天的实例和讲解文章,现在感觉越发的摸不着头脑了。我需要一些实用的技巧,而不是像
这样的例子
class person {
var $name;
function set_name($new_name) {
$this->name = $new_name;
}
function get_name() {
return $this->name;
}
}
$stefan = new person();
$jimmy = new person;<p></p>
<p>$stefan->set_name("Stefan");
$jimmy->set_name("Jimmy");</p>
<p>echo "Stefan's full name: " . $stefan->get_name();
echo "Jimmy's full name: " . $jimmy->get_name(); </p>
像这样的例子让我质疑为什么我不应该(因为它们都在同一个页面中定义)
$name = "Stefan";
echo "Stefan's full name: ".$name;
更短(更少的代码)和更明显的,如果你问我?
拒绝我的项目。
我想做的是一个简单的投资组合网站。因此我只需要 4 个页面,一个主页,一个信息页面,一个关于我的工作的页面和一个联系方式形式。我使用三个表 clients , content和 media我想在我的作品页面上使用它。
我在考虑我的结构并想出了(在我的脑海中,不知道如何实现它)类似的东西
class Database{}
class Content extends Database{}
function showMenu(){}
function showContent{}
class Clients extends Database{}
function showClientList{}
function showClientDetails{}
class Media extends Database{}
我已经制作了一个使用公共(public)方法建立数据库连接的数据库类 query($qry) .我从 Content 开始类,现在看起来像这样:
class Content extends Database {
public function topMenu($page){
$db = new Database();
$db->connect();
$db->query("SELECT m_link, m_title, m_accesskey FROM menu WHERE m_type = 'top'");
$res = $db->getResult();
foreach($res AS $show){
if($page == $show['m_link']){
echo("<li id="active">$show['m_title']."</li>\n");
}else{
echo("<li>$show['m_title']."</li>\n");
}
}
}
}
顺便问一下,这有什么意义吗?
在我的 index.php 上,我有以下几行来显示菜单(工作正常)$content = new Content(); $content->topMenu($_aGET[0]);
我失去它的地方是顶部显示客户列表或客户详细信息的方式,这取决于变量$_aGET[0] (其中包含 url)
假设我想显示客户的详细信息,因此我需要所有三个表的记录,所以通常我会使用几个连接,就像这样
$query = "
SELECT cl.c_id, cl.c_client, cl.c_client_desc, ncc.clco_cl_id, ncc.clco_co_id, co.c_content, ncm.clme_me_id, ncm.clme_cl_id, GROUP_CONCAT(me.m_link) AS images_link
FROM clienten AS cl
LEFT JOIN norm_cl_co_rel AS ncc ON cl.c_id = ncc.clco_cl_id
LEFT JOIN content AS co ON ncc.clco_co_id = co.c_id
LEFT JOIN norm_cl_me_rel AS ncm ON cl.c_id = ncm.clme_cl_id
LEFT JOIN media AS me ON me.m_id = ncm.clme_me_id
WHERE cl.c_client = '".mysql_real_escape_string($_aGET[1])."'
AND cl.c_language_id = '"._LANGUAGE."'
AND cl.c_active = '1'
";
但据我了解 OOP 思想,我应该为类中定义的每个表都有一个方法(对吗?)但是我要如何加入这些?
罢工>或者我的“故事”看起来像这样:“伙计,放下它并坚持使用过程编码”?
编辑:
好的,在 Fluffeh 的帖子之后,我使用了他的示例并对其进行了一些修改以对其进行测试。问题是我确实得到了一些输出,但不是我想要的。我的输出如下所示
ID: CompanyName C Desc: C Media: : : : : :
while i should get (values are in the database):
ID: CompanyName CompanyName Desc: CompanyName is a company Media: : Image 1 : Image 2 : Image 3 : Image 4 : Image 5
My code looks like so:
class media{
public $type;
public $title;
public $image;
public $desc;
}
class client{
public $name;
public $desc;
}
class clientDetails{
private $clientID;
public $clientName;
public $clientDesc;
public $clientMedia = array();
public $clientMediaFiles = 0;
public function __construct($myID){
$this->clientID = $myID;
}
public function getMyDetails(){
$db = new Database();
$db->connect();
$db->query("
SELECT c_client, c_client_desc
FROM clienten
WHERE c_client = '".mysql_real_escape_string($this->clientID)."'
");
foreach($db->getResult() as $client){
$this->name = $client['c_client'];
$this->desc = $client['c_client_desc'];
}
$db = new Database();
$db->connect();
$db->query("
SELECT ncm.clme_me_id, ncm.clme_cl_id, cl.c_id, me.m_id, me.m_type, me.m_title, me.m_desc, me.m_link
FROM norm_cl_me_rel AS ncm
LEFT JOIN clienten AS cl ON cl.c_id = ncm.clme_cl_id
LEFT JOIN media AS me ON me.m_id = ncm.clme_me_id
WHERE me.m_id IN(1,2,3,4,5)
");
foreach($db->getResult() as $media){
$this->clientMedia[$i]= new media();
$this->clientMedia[$i]->type = $media['m_type'];
$this->clientMedia[$i]->title = $media['m_title'];
$this->clientMedia[$i]->image = $media['m_image'];
$this->clientMedia[$i]->desc = $media['m_desc'];
$this->clientMediaFiles++;
}
}
public function displayMyResults(){
echo "ID: $this->clientID";
echo "<div><h3>".$this->name."</h3>";
echo "Desc: ".$this->desc."<br>";
echo "Media:<br>";
for($i=0;$i<$this->clientMediaFiles;$i++){
echo $this->clientMedia[$i]->title." : ".$this->clientMedia[$i]->desc."<br>";
}
echo "</div>";
}
}
最佳答案
继续使用 OOP。一旦你得到它,你将永远不想回到讨厌的、麻烦的、令人讨厌的、可怕的、疯狂的程序代码。
举个例子:假设我想显示客户的详细信息,因此我需要所有三个表的记录,所以通常我会使用几个连接,就像这样...
这是一个很好的例子,可以用来向您展示 OOP 的用途。
为 ClientDetails 创建一个类
突然你一个类只有几行代码,但是2行代码就可以完美展示你的数据。
我将很快添加一些示例代码,看看我是否可以翻找我的一些类来进行演示。
编辑:该死,没有翻阅旧类,对于这个来说太详细了,但我写了一些代码作为示例:
<?php
class clientContact
{
public $name;
public $phone;
}
class clientDetails
{
private $clientID; //only this class can access this variable.
public $clientName; // Anything can change these.
public $clientPhone;
public $additionalContacts= array();
public $associates=0;
public function __construct($myID)
// This is a magic function that is called every time we make a new object of this class.
{
$this->$clientID=$myID;
}
public function getMyDetails()
// This function will query the database to get it's information properly
// and populate itself with everything it needs. You could do this as part
// of the __construct() call, but I didn't want to do TOO much code.
{
$sql="select clientName, clientPhone from clients where clientID=".$this->clientID.";";
// skipping over full SQl bits...
foreach($stmt as $clientContact)
{
$this->clientName=$clientContact->clientName;
$this->clientPhone=$clientContact->clientPhone;
}
$sql="select clientName, clientPhone from associates where assocID=".$this->clientID.";";
// skipping over full SQl bits...
foreach($stmt as $clientContact)
{
$this->additionalContacts[$i]= new clientContact();
$this->additionalContacts[$i]->name=$clientContact->name;
$this->additionalContacts[$i]->phone=$clientContact->phone;
$this->associates++;
}
}
public function displayMyResults()
// This function will simply display everything it has in a nicely format
{
echo "<div><h3>".$this->clientName."</h3>";
echo "My contact phone number is :".$this->phone."<br>";
echo "My associates are:<br>";
for($i=0;$i<$this-associates;$i++)
{
echo $this->additionalContacts[$i]->name." : ".$this->additionalContacts[$i]->phone."<br>";
}
echo "</div>";
}
}
?>
天哪,这又长又可怕对吧?
不是真的。原因如下。
当然,类中有一些代码,但是现在,您可以在主页上执行以下操作:
<?php
$someArray=array(36, 25, 76);
// This could be from a query, or a form, or anything else
for($i=0;$i<count($someArray);$i++)
{
$currentContact= new clientDetails($someArray[$i]);
// This is how we create the object.
$currentContact->getMyDetails();
// This now tells the object to get it's own data
$currentContact->displayMyResults();
// This now displays the data in the object to the page.
echo "<hr>";
unset($currentContact);
}
?>
通过这个 TINY 代码片段,您刚刚显示了所有联系人,并根据需要设置了格式,并且完全按照您想要的方式完美地显示了所有联系人。
现在想象一下,您将这些类型的对象用于所有内容,而不是像这样的一个小例子。论坛上的帖子?一个对象。业务 KPI 的复杂计算?一个对象可以获取它拥有的所有数据,然后计算一个预测,将结果显示在图表中并将其通过电子邮件发送给需要它的用户。
如果您的背景是从上到下执行的 HTML 和 PHP 脚本,OOP 的学习曲线可能会很陡峭,但是当您开始掌握它时,您会希望自己从一开始就学会了它。
编辑:
您的查询中似乎没有 m_image 列:
$db = new Database();
$db->connect();
$db->query("
SELECT cl.c_id, ncm.clme_me_id, ncm.clme_cl_id, me.m_type, me.m_title, me.m_desc, me.m_link, m_image
FROM clienten AS cl
LEFT JOIN norm_cl_me_rel AS ncm ON cl.c_id = ncm.clme_cl_id
LEFT JOIN media AS me ON me.m_id = ncm.clme_me_id
WHERE me.m_id IN(1,2,3,4,5)
");
foreach($db->getResult() as $media){
$this->clientMedia[$i]= new media();
$this->clientMedia[$i]->type = $media['m_type'];
$this->clientMedia[$i]->title = $media['m_title'];
$this->clientMedia[$i]->image = $media['m_image'];
$this->clientMedia[$i]->desc = $media['m_desc'];
$this->clientMediaFiles++;
}
编辑 2:我不是 100% 确定,但可能是返回的字段名称。尝试用这个替换查询:
SELECT cl.c_id as c_id, ncm.clme_me_id as clme_me_id, ncm.clme_cl_id as clme_cl_id, me.m_type as m_type, me.m_title as m_title, me.m_desc as m_desc, me. as m_link
FROM clienten AS cl
LEFT JOIN norm_cl_me_rel AS ncm ON cl.c_id = ncm.clme_cl_id
LEFT JOIN media AS me ON me.m_id = ncm.clme_me_id
WHERE me.m_id IN(1,2,3,4,5)
关于PHP OOP 方法困难,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11755832/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)