benanamen Posted October 6, 2016 Share Posted October 6, 2016 (edited) In the following class, it works with or without line 4 public $num. So why is it there? <?php class mathematics { public $num; public function addTwo() { return $this->num + 2; } } $math = new mathematics; $math->num = 3; echo $math->addTwo(); ?> Edited October 6, 2016 by benanamen Quote Link to comment https://forums.phpfreaks.com/topic/302291-oop-properties/ Share on other sites More sharing options...
Jacques1 Posted October 6, 2016 Share Posted October 6, 2016 (edited) PHP can add properties dynamically, but you should avoid this at any cost, because you won't get documentation, you won't get code completion, and you cannot easily distinguish between legitimate attributes which just aren't declared and plain programming errors (e. g. mistyped attributes). In this particular example, it's also problematic that the attribute can be uninitialized when you use it. Edited October 6, 2016 by Jacques1 Quote Link to comment https://forums.phpfreaks.com/topic/302291-oop-properties/#findComment-1538090 Share on other sites More sharing options...
benanamen Posted October 6, 2016 Author Share Posted October 6, 2016 (edited) Appreciate the response, but when it comes to OOP I need answers really dumbed down until I get a grasp of this. I want to understand why to do things and not just do it because it works. PHP can add properties dynamically How does it do that? but you should avoid this at any cost How do you avoid it? By having the line in question? Would that line generally be public or private? Is it just because you won't get documentation or are their more reasons? Is their any special name for a property with no value like the line mentioned? you won't get code completion, and you cannot easily distinguish between legitimate attributes which just aren't declared and plain programming errors Lost me here. I looked up code completion and it seems to only apply to IDE's and thus far is the only place I have been aware of it. The rest is russian to me so far. Edited October 6, 2016 by benanamen Quote Link to comment https://forums.phpfreaks.com/topic/302291-oop-properties/#findComment-1538091 Share on other sites More sharing options...
benanamen Posted October 6, 2016 Author Share Posted October 6, 2016 (edited) So now this tutorial I am studying uses another example and the same type of line previously asked about equals an empty string public $username = "";. I tried it without the empty string like public $username; and it still works. What is there to know about this? Any recommendations that give detailed explanations of the code? * Edit, now elsewhere I am also seeing var $some_variable; for the same type of line. So there is Public, Private, Protected and Var? OOP is making my head hurt. <?php class Member { public $username = ""; } $member = new Member(); $member->username = "Fred"; echo $member->username; ?> Edited October 6, 2016 by benanamen Quote Link to comment https://forums.phpfreaks.com/topic/302291-oop-properties/#findComment-1538092 Share on other sites More sharing options...
Jacques1 Posted October 6, 2016 Share Posted October 6, 2016 (edited) PHP lets you do almost anything, but if you want to learn proper OOP, you should adhere to very strict standards – regardless of what the PHP interpreter says. The reason why you should declare attributes (with a line saying public/protected/private $attName) is that you need to know the attributes of an object to write correct code. When I type $obj->num with a properly declared attribute, my IDE immediately gives me a lot of important information: whether the attribute actually exists (I could have made a mistake) the type and meaning of the attribute through the documentation the initial value where the attribute comes from (could be a superclass) and where it's used With dynamically added attributes, you get none of this. You're flying blind. This may be OK for a simple test class, but when you're dealing with a complex architecture and dozens of classes, you definitely need to know what's going on. “It works” isn't enough. The point of initializing an attribute (with public/protected/private $attName = ...) is to make sure the attribute has a reasonable default value as opposed to null. Unfortunately, the example code is a fairly bad example. It would make a lot more sense to assign the name through the constructor: <?php class Member { /** * @var string */ protected $username; /** * @param string $username */ public function __construct(string $username) { $this->username = $username; } } This provides several benefits: A member object is always completely initialized with a valid name. In your case, the name is initially empty. PHP can check the type of the input (only in PHP 7). In your case, nothing prevents me from setting the username to 123. The attribute is safe, because it cannot simply be manipulated from the outside. In your case, any part of the application can change it to any nonsense value at any time. The latter is also the reason why attributes should almost never be public. You don't want uncontrolled changes and nonsense values. If you need to expose the attribute at all, you do it through getters and setters. A getter method simply returns the attribute value so that it can be read (but not changed) from the outside. A setter method takes one argument, validates it and assigns it to the attribute (if the value is valid). This allows the outside world to change the attribute in a controlled(!) manner. <?php class Member { /** * @var string */ protected $username; /** * Getter for the username * * @return string */ public function getUsername() { return $this->username; } /** * Setter for the username; this must be omitted if the username should be read-only * * @param string $username the new username */ public function setUsername(string $username) { // validation (can be much more strict) if ($username == '') { throw new InvalidArgumentException('Username cannot be empty'); } $this->username = $username; } /** * @param string $username */ public function __construct(string $username) { $this->username = $username; } } * Edit, now elsewhere I am also seeing var $some_variable; for the same type of line. So there is Public, Private, Protected and Var? No. The var keyword comes from PHP 4 and is long obsolete. If you see it being used in a tutorial, pick a different tutorial. Edited October 6, 2016 by Jacques1 Quote Link to comment https://forums.phpfreaks.com/topic/302291-oop-properties/#findComment-1538093 Share on other sites More sharing options...
benanamen Posted October 7, 2016 Author Share Posted October 7, 2016 (edited) The reason why you should declare attributes (with a line saying public/protected/private $attName) is that you need to know the attributes of an object to write correct code. That answers an upcoming question I had. With all these classes in an app, how do you know how to use them. Unfortunately, the example code is a fairly bad example. That is the problem I am going to run into until I get this down. I wouldnt know bad OOP staring me in the face. Any OOP tutorial recommendations? The var keyword comes from PHP 4 and is long obsolete. If you see it being used in a tutorial, pick a different tutorial. This is worth it's weight in gold! When you explain things the way you just did I can get a good grasp of it. All the tutorials I have seen don't really explain in detail. They just say do this, do that. So, if I understand correctly I don't want to do protected $username =""; right? Edited October 7, 2016 by benanamen Quote Link to comment https://forums.phpfreaks.com/topic/302291-oop-properties/#findComment-1538094 Share on other sites More sharing options...
ginerjm Posted October 7, 2016 Share Posted October 7, 2016 How do you know how to use them? Well - you wrote them presumably, so use them for the thing(s) that they were designed for. As for your original question. Creating a property inside a class without the declaration at the top is like creating a local variable in a normal (non-oop) function. It's local to the scope and is not known outside of that function, although your examples may lead to that being not true. When you create an object property inside a method you are going against the concept of an object. An object is a well-defined thing that has properties and methods and is meant to function as the entity that it was defined as, not with additional "things" tacked on that are not defined and not known to be part of the object. IOW - it's kinda like what M$ does with their software, and we know where that gets you. 1 Quote Link to comment https://forums.phpfreaks.com/topic/302291-oop-properties/#findComment-1538095 Share on other sites More sharing options...
benanamen Posted October 7, 2016 Author Share Posted October 7, 2016 When extending the class, does it matter if you do classname::method or if you do parent::method? Is there a best practice on this? Quote Link to comment https://forums.phpfreaks.com/topic/302291-oop-properties/#findComment-1538096 Share on other sites More sharing options...
Jacques1 Posted October 7, 2016 Share Posted October 7, 2016 Any OOP tutorial recommendations? Not really. Unfortunately, PHP isn't a great language for learning OOP, because all OOP parts have been added on top of the procedural paradigm at a very late stage. This is why they often seem unnatural and hard to understand. If you're really interested in OOP, you should consider learning it together with a language that has been designed in an object-oriented manner from the ground up. My personal favorite is Ruby (which is a scripting language), and of course there are classical OOP language like Java (which is heavier). So, if I understand correctly I don't want to do protected $username =""; right? In the above case, you want a protected attribute without initialization. It doesn't hurt to initialize the attribute with an empty string, but it's simply unnecessary when the name is immediately assigned within the constructor. Initialization makes sense when you don't assign a value in the constructor. Quote Link to comment https://forums.phpfreaks.com/topic/302291-oop-properties/#findComment-1538097 Share on other sites More sharing options...
Jacques1 Posted October 7, 2016 Share Posted October 7, 2016 When extending the class, does it matter if you do classname::method or if you do parent::method? Is there a best practice on this? Best practice is to use parent, because it allows you do change the class names at any time. If the names are hard-coded everywhere in the methods, that's a lot more difficult. Quote Link to comment https://forums.phpfreaks.com/topic/302291-oop-properties/#findComment-1538098 Share on other sites More sharing options...
Jacques1 Posted October 7, 2016 Share Posted October 7, 2016 As for your original question. Creating a property inside a class without the declaration at the top is like creating a local variable in a normal (non-oop) function. It's local to the scope and is not known outside of that function, although your examples may lead to that being not true. It actually isn't true. An attribute created within a method is a real attribute. It's not limited to the method scope in any way. When you create an object property inside a method you are going against the concept of an object. An object is a well-defined thing that has properties and methods and is meant to function as the entity that it was defined as, not with additional "things" tacked on that are not defined and not known to be part of the object. IOW - it's kinda like what M$ does with their software, and we know where that gets you. Dynamic properties are valid (that's why the magic methods __get() and __set() exist). They just shouldn't be used unnecessarily. Quote Link to comment https://forums.phpfreaks.com/topic/302291-oop-properties/#findComment-1538099 Share on other sites More sharing options...
benanamen Posted October 7, 2016 Author Share Posted October 7, 2016 Not really. Unfortunately, PHP isn't a great language for learning OOP, because all OOP parts have been added on top of the procedural paradigm at a very late stage. This is why they often seem unnatural and hard to understand. If you're really interested in OOP, you should consider learning it together with a language that has been designed in an object-oriented manner from the ground up. My personal favorite is Ruby (which is a scripting language), and of course there are classical OOP language like Java (which is heavier). Am I better off heading straight to ruby first? Does ruby knowledge transfer over to Php OOP? Are you on any ruby help forums? Quote Link to comment https://forums.phpfreaks.com/topic/302291-oop-properties/#findComment-1538100 Share on other sites More sharing options...
Jacques1 Posted October 7, 2016 Share Posted October 7, 2016 Ruby takes a slightly different approach to OOP, but that's a good thing: It's more pure, more elegant and has many best practices already built in: Every value is an object, including numbers, strings, booleans, arrays etc. Even classes are objects which allows for some interesting design choices: Ruby doesn't need the concept of static attributes or methods, because a class object can have methods and attributes just like any other object. There's a clear class hierarchy with BasicObject as the root node. There's no raw attribute access like in PHP. A object only exposes methods, and attributes are implemented as a getter and/or setter method together with an internal object variable. So everything I told you above is already part of the language. Error handling is implemented purely with exceptions. There are no low-level errors like in PHP. So instead of fumbling with error handlers and all kinds of edge cases, you can simply wrap the main code in a begin-rescue statement (Ruby's equivalent of try-catch). The every-value-is-an-object rule in particular makes the language very elegant. For example, instead of using a for loop, you can simply call the upto() or downto() method of an integer: 1.upto(10) do |i| print i end vs. for ($i = 1; $i <= 10; $i++) { echo $i; } Instead of using a foreach loop, you call the each() method of the collection object (similar to jQuery): chars = ['H', 'e', 'l', 'l', 'o'] chars.each do |ch| print ch end vs. $chars = ['H', 'e', 'l', 'l', 'o']; foreach ($chars as $ch) { echo $ch; } So, yes, I would give it a try and jump straight to Ruby. You'll learn a lot about OOP, you'll learn a new language, and you might actually like what you see. Unlike PHP, Ruby has some great books (particularly the famous “pickaxe book” and a well-written introduction from the language author), code you find online is usually OK, and there are plenty of knowledgeable programmers around. If there's permanent interest, I'm sure we can open a new Ruby forum here. One small warning, though: Ruby is a general-purpose language, so it's less plug-and-play when it comes to web applications. For hobby stuff, you can install the Sinatra framework and use its built-in webserver. For more serious applications, you'll need an application server like Puma behind Apache/nginx. Quote Link to comment https://forums.phpfreaks.com/topic/302291-oop-properties/#findComment-1538103 Share on other sites More sharing options...
benanamen Posted October 7, 2016 Author Share Posted October 7, 2016 (edited) If there's permanent interest, I'm sure we can open a new Ruby forum here. You have my vote as well as for other technologies. I posted to Comments https://forums.phpfreaks.com/topic/302292-new-forums/ Edited October 7, 2016 by benanamen Quote Link to comment https://forums.phpfreaks.com/topic/302291-oop-properties/#findComment-1538106 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.