jxwd Posted December 4, 2023 Share Posted December 4, 2023 Hi All, I have $this->debug which I append ... debug is a property in pass class. Utility is another class I am injecting. It works fine at the top 2 levels. I can use utility in the third level but can't append the debug property. IE this only works top 2 levels. $this->debug .= 'new comment </ br>'; In Main (top level) I declare function __construct(){ $this->pass = new Pass(); $this->util = new Utility($this->pass); $this->consignments_pages = new ConsignmentsPages($this->util, $this->pass); Then in ConsignmentsPages next level function __construct($util, $pass){ $this->pass = $pass; $this->util = $util; $this->consignments_actions = new ConsignmentsActions($this->util, $this->pass); In this level I can append as follows and it works great. $this->debug .= 'new comment </ br>'; Then in ConsignmentsActionsnext level ConsignmentsActions($this->util, $this->pass) $this->pass = $pass; $this->util = $util; I can used the utility functions. But when I append to $this->debug .= 'new comment </ br>'; It doesn't append, when it's outputted at the top level. Advice please 🙂 (nb I am fairly new to OO) Thank you! Quote Link to comment https://forums.phpfreaks.com/topic/317507-injecting-a-debug-object-more-than-2-levels/ Share on other sites More sharing options...
requinix Posted December 4, 2023 Share Posted December 4, 2023 You've described some stuff that doesn't make sense. Like, you say "$this->debug" but I can't tell which class you're putting that in. Shouldn't it be more like $this->util->debug, or $this->pass->debug? 1. Post more code. Especially the stuff showing what $debug is and where it's being used. 2. Describe what you're trying to do. Because it sounds like you're approaching this in the wrong way - any time you need a class named like "Utility", that's an ominous sign. It kinda sounds like you're reinventing the concept of logging... Quote Link to comment https://forums.phpfreaks.com/topic/317507-injecting-a-debug-object-more-than-2-levels/#findComment-1613299 Share on other sites More sharing options...
jxwd Posted December 4, 2023 Author Share Posted December 4, 2023 Ahhh yes sorry exactly that: $this->pass->debug .= 'comment <br />'; It is used in methods in all three classes to show states as the code runs. For example function evaluate_page () { $this->pass->debug .= $this->util->clock().'START(method) evaluate_page.page_name.'.$this->util->read_session('btn_nav').'<br />'; I am using this property in all three Classes to see states of the code in history... It works at the top two classes. Utility is another class I am using for database functions, session variables and other commonly reused things like drop menus. Very open to doing it another way 🙂 Thank you Quote Link to comment https://forums.phpfreaks.com/topic/317507-injecting-a-debug-object-more-than-2-levels/#findComment-1613300 Share on other sites More sharing options...
Solution requinix Posted December 5, 2023 Solution Share Posted December 5, 2023 6 hours ago, jxwd said: I am using this property in all three Classes to see states of the code in history... It works at the top two classes. Then all I can tell you is you're doing something differently in this third class that you were/weren't doing in the other two classes. Because PHP isn't going to care about how far from the "top" you are: an object is an object. If you can do ->debug on a particular object from one place then* you can do the same ->debug on the same object from a different place. 6 hours ago, jxwd said: Very open to doing it another way 🙂 Alright. But one question: Doing what another way? * Technically that's not always the case, but it shouldn't be an issue as far as this is concerned. Quote Link to comment https://forums.phpfreaks.com/topic/317507-injecting-a-debug-object-more-than-2-levels/#findComment-1613303 Share on other sites More sharing options...
jxwd Posted December 5, 2023 Author Share Posted December 5, 2023 Quote Then all I can tell you is you're doing something differently in this third class that you were/weren't doing in the other two classes. Yes thought so but couldn't see a difference, as was declaring everything the same... But now I can it's how I am calling the methods. So problem solved. Quote Doing what another way? How to bring states of the code for debugging and how to use regularly used pieces of code as I have done with a utility class. Thanks Quote Link to comment https://forums.phpfreaks.com/topic/317507-injecting-a-debug-object-more-than-2-levels/#findComment-1613312 Share on other sites More sharing options...
requinix Posted December 5, 2023 Share Posted December 5, 2023 6 hours ago, jxwd said: How to bring states of the code for debugging That doesn't really say a whole lot. I think what you're doing is essentially logging: when a piece of code performs some action, you want to record a log of the fact that it happened, as well as potentially some supplemental information about it. For example, you've got this "new comment" thing. That sounds like a log message. Additional information about that could be the author of the comment, what they were commenting on, and the timestamp of when they made it. If you just want something that lives for the duration of the code - you don't want this going to a file, or saved to a database, or anything persistent like that - then some parts might not be as useful as others (like the timestamp). Consider this simple function: function log_message(string $message, array $data = []) { $output = date("[Y-m-d H:i:s] ") . $message . PHP_EOL; foreach ($data as $key => $value) { $string = is_scalar($value) ? $value : json_encode($value); $output .= "\t{$key} = {$string}" . PHP_EOL; } file_put_contents("/path/to/file.log", $output, FILE_APPEND | LOCK_EX); } used like log_message("New comment", ["author" => $authorId, "page" => $pageId]); Instead of building up some "debug" string living in a class somewhere, you call that function and it will immediately write the message to a file. You can then open that log file (remember to change the path) in any decent editor and watch messages get written to it when you browse your site. There is actually some better stuff that's built-in to PHP you can use, so the above is really more of an example of the concept of logging. Does that make sense? 6 hours ago, jxwd said: and how to use regularly used pieces of code as I have done with a utility class <opinion> PHP is a functional language, meaning it has functions that don't have to live within classes. It makes sense to occasionally use functions for things that don't need to belong in a class - such as that "log_message" above. The one disadvantage is that PHP can't (yet) autoload functions like it can classes, so in order to get them available everywhere you need to make sure the file(s) with the functions are always included; normally a site has a single entrypoint file, like /index.php, through which all requests pass, and that would be a great place to include the necessary files. A similar approach is static methods in a class: it's kinda object-oriented in that there's a class, but really the class is just a container for functions. A container that can be autoloaded by PHP. And with static methods, you don't have to pass around these "util" (or "pass"?) objects everywhere. That's a reasonable compromise, but I'm not thrilled as (a) it's just an end-run around plain functions and (b) it lends itself to organically-grown utility classes. So really, the first step to getting rid of a utility class is to decide whether the functionality you have doesn't actually have an appropriate and specific class for the various methods after all. Consider the log_message function having been added to a Utility class. You might start with it as a regular (non-static) method on a Utility class. Then you realize that you can make it static, as you don't really need an instance of the Utility class in order to write some stuff to a file, however it's still a "utility". The next step is to realize that logging is a concept which can have its own class. Like a class named Log, or Logger. That's better than a utility as you've taken a specific requirement (log a message) and found a specific class (Thing That Logs Messages) for it to belong in. (And there's more to think about after that...) But occasionally you do end up with functions that don't really belong anywhere. For example, I have some code that needs to check if an array contains an item matching some conditions, as determined by an arbitrary function that returns true/false. function is_even_number($number) { return ($number % 2) == 0; } PHP doesn't have a built-in function that can do what I need, so I have my own called "array_contains". function array_contains(array $array, callable $function): bool { foreach ($array as $key => $value) { if ($function($value, $key)) { return true; } } return false; } used like array_contains([1, 2, 3], "is_even_number") // true array_contains([1, 3, 5], "is_even_number") // false I'm not going to create an Array class just so I can put this function into it, and for reasons that are more complicated than I need to get into here. So it's just a plain function. </opinion> Point is, there are two main alternatives to a utility class: (1) go ahead and use a plain function because that's how PHP works and it's totally fine that not every single thing in PHP is an object, or (2) conclude that a particular thing could actually make sense in a separate, dedicated class because there's potentially more to the general concept that you might want to account for in the future. 1 Quote Link to comment https://forums.phpfreaks.com/topic/317507-injecting-a-debug-object-more-than-2-levels/#findComment-1613332 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.