Skip to content

Add factory methods for DatePeriod and ReflectionMethod #6754

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from

Conversation

kocsismate
Copy link
Member

@kocsismate kocsismate commented Mar 5, 2021

This PR proposes to add the following factory methods:

class DatePeriod
{
    public static function createFromRecurrences(DateTimeInterface $start, DateInterval $interval, int $recurrences, int $options = 0): static {}

    public static function createFromDates(DateTimeInterface $start, DateInterval $interval, DateTimeInterface $end, int $options = 0): static {}

    public static function createFromIso8601(string $specification, int $options = 0): static {}
}

class ReflectionMethod
{
    public static function createFromMethodName(string $method): static {}
}

The longer-term advantage of these added methods is that we could get rid of the overloaded signatures of DatePeriod::__construct() and ReflectionMethod::__construct() in PHP 9 after a deprecation phase in PHP 8.x (https://wiki.php.net/rfc/deprecations_php_8_1#dateperiodconstruct and https://wiki.php.net/rfc/deprecations_php_8_1#passing_a_method_name_as_the_first_parameter_to_reflectionmethodconstruct).

P.S. I don't have any strong preference about the method names, and the current ones should be considered as WIP ones. :)

@kocsismate kocsismate changed the title Add factory methods for classes with overloaded constructors (DatePeriod, ReflectionMethod) Add factory methods for DatePeriod and ReflectionMethod Mar 5, 2021
ZVAL_COPY_VALUE(return_value, &object);
}

PHP_METHOD(DatePeriod, createFromDates)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

other candidates I thought about: createBetweenDates, createBetweenStartAndEnd, createFromStartAndEnd

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I would prefer createFromStartAndEnd, and I would also switch the order of arguments to:

    public static function createFromStartAndEnd(DateTimeInterface $start, DateTimeInterface $end, DateInterval $interval, int $options = 0): static {}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another suggestion would be to use createFromEndpoints or createFromDatepoints to imply that the DatePeriod endpoints are expressed using DateTimeInterface objects.

@@ -398,6 +398,12 @@ public static function __set_state(array $array) {}

class DatePeriod implements IteratorAggregate
Copy link
Member Author

@kocsismate kocsismate Mar 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should decide what to do with the overloaded constructor:

  • do nothing so that the overloaded signature remains supported forever
  • deprecate it in 8.x and remove it in 9.0 altogether
  • choose one "canonical" signature, deprecate the others in 8.x, and get rid of them in 9.0

Depending on the outcome, we could only have 2 factory methods, and the 3rd signature could be implemented by the constructor

@kocsismate
Copy link
Member Author

@nikic Now that there is an implementation for these methods... Do you think it's a good idea to vote about their inclusion in PHP 8.1 and the deprecation of the related constructor behavior in PHP 8.2 as part of the 8.1 Deprecations RFC?

size_t isostr_len = 0;
static void construct_date_period(
INTERNAL_FUNCTION_PARAMETERS, zval *object, zval *start, zval *end, zval *interval, zend_long recurrences,
zend_long options, char *isostr, size_t isostr_len
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer it if this initialisation function gets split as well. The old __construct should use the new (3) initialisation methods, which also makes it easier to clean up in for example PHP 9.0. It can also mean that error and bounds checking (for example, recurrences can't be negative) to the right and logical position.

@iluuu1994
Copy link
Member

@kocsismate Are there plans to pursue this RFC?

@kocsismate
Copy link
Member Author

@iluuu1994 yes, absolutely! My plan is to first fix the easier issues in stubs (mostly declaring the missing constants) and then continue with the improvements which need more thinking.

@jurchiks
Copy link

jurchiks commented Sep 15, 2022

My suggestions for the methods:

class DatePeriod
{
    public function __construct(string $isoRecurringInterval, int $options = 0)

    public static function fromStartAndEnd(DateTimeInterface $start, DateInterval $interval, DateTimeInterface $end, int $options = 0): static

    public static function fromStartAndRecurrences(DateTimeInterface $start, DateInterval $interval, int $recurrences, int $options = 0): static

    public static function fromEndAndRecurrences(DateTimeInterface $end, DateInterval $interval, int $recurrences, int $options = 0): static

    public function __toString(): string // returns ISO8601 formatted recurring interval
}

I'm pretty sure that the static methods are in order of popularity as written here, although perhaps that can be researched (though constructor overloads make this problematic).
IMO the prefix create is completely redundant and adds no extra meaning to the already pretty clear name. I don't believe you can misunderstand what DatePeriod::fromStartAndRecurrences(...) will do; it's a static method that returns an instance of DatePeriod, obviously it's going to "create" the new instance because it can't come from anywhere else, there's no need to explicitly say it. It's also closer to natural language: "date period from start and occurrences" vs "date period create from start and occurrences"; the latter one just sounds weird.

In addition to that, having the string constructor be the main default one, and having a __toString method would enable easy and convenient serializing/unserializing to/from database.

P.S. I don't understand why including the end date is opt-in; to me it makes far more sense for it to be opt-out, same as EXCLUDE_START_DATE.

@adoy adoy removed this from the PHP 8.2 milestone Feb 16, 2023
@kocsismate
Copy link
Member Author

Closing in favor of #11703

@kocsismate kocsismate closed this Jul 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants